我有一个需要重复的数据框。
from io import StringIO
import pandas as pd
audit_trail = StringIO('''
course_id AcademicYear_to months TotalFee
260 2017 24 100
260 2018 12 140
274 2016 36 300
274 2017 24 340
274 2018 12 200
285 2017 24 300
285 2018 12 200
''')
df11 = pd.read_csv(audit_trail, sep=" " )
对于课程编号260,每年有2个条目。 2017年和2018年。我需要重复月份组的年份。 我将再获得2行,2018年为24个月,2017年为12个月。最终数据框将如下所示......
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=" " )
我试图将相同的数据帧连续两次,但这并没有解决问题。我需要改变年份和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个条目。问题是课程编号260,这是24个月课程,但只有1个条目。 加入不会返回该课程的第二年。
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
此情况下的预期计数为
274 6
285 4
260 2
这是因为即使id 274有3年,课程持续时间也只有24个月。即使持续时间为24个月只有260条记录,它也应该返回2条记录。 (本年度一次,当前年份+ 1次)
答案 0 :(得分:2)
不漂亮!
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
答案 1 :(得分:2)
IIUC我们merge df11
可以自己:
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