2017-08-19 13 views
2

私は自分自身を繰り返す必要のあるデータフレームを持っています。コースの所要時間に応じて行を繰り返す

コースid260には、年間2つのエントリがあります。 2017年と2018年です。私は月のグループのために年を繰り返す必要があります。 私は

audit_trail = StringIO(''' 
course_id AcademicYear_to months TotalFee 
260 2017 24 100 
260 2018 24 100 
260 2017 12 140 
260 2018 12 140 
274 2016 36 300 
274 2017 36 300 
274 2018 36 300 
274 2016 24 340 
274 2017 24 340 
274 2018 24 340 
274 2016 12 200 
274 2017 12 200 
274 2018 12 200 
285 2017 24 300 
285 2018 24 300 
285 2017 12 200 
285 2018 12 200 
''') 

df12 = pd.read_csv(audit_trail, sep=" " ) 

が、私は二度同じデータフレームをCONCATしようとした...ヶ月の最終データフレームは次のようになります12のために数ヶ月24および2017年2行以上、2018を取得しますが、それは解決しません問題。私は年を変え、36ヶ月間、データを3回繰り返す必要があります。

pd.concat([df11, df11]) 

オブジェクトによってグループが年を返します。私は、元のデータフレームで各グループの年に参加するだけです。

df11.groupby('course_id')['AcademicYear_to'].apply(list) 

260   [2017, 2018] 
274 [2016, 2017, 2018] 
285   [2017, 2018] 

シンプルなレコードは年の数と一致した場合に動作することができます参加します。例えば、コースID 274は48ヶ月、285は24ヶ月の継続時間を有し、それぞれ3,2エントリーがある。問題は24ヶ月のコースですが、エントリーが1つしかないコースID 260です。 に参加すると、そのコースの2年目はに戻りません。

df11=pd.read_csv('https://s3.amazonaws.com/todel162/myso.csv') 

df11.course_id.value_counts() 
274 3 
285 2 
260 1 

df=df11.merge(df11[['course_id']], on='course_id') 

df.course_id.value_counts() 
274 9 
285 4 
260 1 

月数も考慮するクエリを記述することはできますか?


次のクエリは、単純結合が期待される結果を返さないレコードを返します。

df11=pd.read_csv('https://s3.amazonaws.com/todel162/myso.csv') 
df11['m1']=df11.groupby('course_id').course_id.transform(lambda x: x.count() * 12) 
df11.query('m1 != duration_inmonths') 

df11.course_id.value_counts() 
274 3 
285 2 
260 1 

df=df11.merge(df11[['course_id']], on='course_id') 

df.course_id.value_counts() 
274 9 
285 4 
260 1 

この場合の予想される数は、ID 274のための3年間があっても、コースの期間はわずか24ヶ月であるため、これは

274 6 
285 4 
260 2 

です。また、期間が24か月間であるため、260レコードが1つしかない場合でも、2レコードが返されます。 (今年は1回、もう1年は+ 1)

答えて

2

我々は自分自身にmergedf11をすることができますIIUC:

In [14]: df11.merge(df11[['course_id']], on='course_id') 
Out[14]: 
    course_id AcademicYear_to months TotalFee 
0   260    2017  24  100 
1   260    2017  24  100 
2   260    2018  12  140 
3   260    2018  12  140 
4   274    2016  36  300 
5   274    2016  36  300 
6   274    2016  36  300 
7   274    2017  24  340 
8   274    2017  24  340 
9   274    2017  24  340 
10  274    2018  12  200 
11  274    2018  12  200 
12  274    2018  12  200 
13  285    2017  24  300 
14  285    2017  24  300 
15  285    2018  12  200 
16  285    2018  12  200 
+0

データが一貫している場合は動作します。私は私の質問を更新しました。 – shantanuo

2

Not Pretty!

def f(x): 
    idx = x.index.remove_unused_levels() 
    idx = pd.MultiIndex.from_product(idx.levels, names=idx.names) 
    return x.reindex(idx) 

df11.set_index(['months', 'AcademicYear_to']) \ 
    .groupby('course_id').TotalFee.apply(f) \ 
    .groupby(level=[0, 1]).transform('first') \ 
    .astype(df11.TotalFee.dtype).reset_index() 

    course_id months AcademicYear_to TotalFee 
0   260  24    2017  100 
1   260  24    2018  100 
2   260  12    2017  140 
3   260  12    2018  140 
4   274  12    2016  200 
5   274  12    2017  200 
6   274  12    2018  200 
7   274  24    2016  340 
8   274  24    2017  340 
9   274  24    2018  340 
10  274  36    2016  300 
11  274  36    2017  300 
12  274  36    2018  300 
13  285  24    2017  300 
14  285  24    2018  300 
15  285  12    2017  200 
16  285  12    2018  200 
+0

提案された解決策は、テストデータで動作します。しかし、私は繰り返すべき列がたくさんあります。私の質問を更新しました。 – shantanuo

+0

元のデータフレームとの左結合は、私が探していたものを返しました。ありがとう。 – shantanuo

+0

エラーを取得する:例外:一意でない複数のインデックスを処理できません! – shantanuo

関連する問題