我正在尝试找出一种有效的方法(关于代码行数),同时使用group by语句来计算数据帧的条件中值。
下面是我的数据结构:
id date exp d_x yield
1 2/5 3/10 .2 0.01
1 2/5 3/10 .48 0.09
1 2/5 3/10 .67 0.10
1 2/5 3/10 .77 0.04
1 2/5 4/15 .2 0.31
1 2/5 4/15 .65 0.10
... ... ... .. ...
29 5/4 10/20 .24 0.21
我基本上想要的是: 新列-称为“ median_yield”,它是所有组的所有产量的中位数,d_x <.5。
grouping = (id, date, exp)
我尝试过的是以下内容:
df.query("d_x < .5").groupby(['id', 'date', 'Expiration'], as_index=False)['yield'].transform('median')
但是,结果很好,但是对于d_x> .5,结果是Nan。
所需的输出:
id date exp d_x yield median_y
1 2/5 3/10 .2 0.01 0.5
1 2/5 3/10 .48 0.09 0.5
1 2/5 3/10 .67 0.10 0.5
1 2/5 3/10 .77 0.04 0.5
1 2/5 4/15 .2 0.31 0.31
1 2/5 4/15 .65 0.10 0.31
... ... ... .. ... ....
29 5/4 10/20 .24 0.21 ....
示例: 数据框:
df1 = {'id' : [1, 1, 1, 1, 1, 2, 2, 2, 2, 2],
'date' : ["2/5", "2/5", "2/5", "2/5", "2/5", "3/5", "3/5", "3/5",
"3/5", "3/5"],
'exp' : ["3/10", "3/10", "3/10", "3/10", "3/10", "4/15", "4/15",
"4/15", "4/15", "4/15"],
'd_x' : [.2, .431, .501, .56, .77, .10, .15, .61, .32, .91],
'yield' : [.01, .04, .05, .10, .05, .012, .10, .20, .12, .05]}
df1 = pd.DataFrame(df1)
df1["median_y"] = df1.query("d_x < .5")\
.groupby(['id', 'date', 'exp'])\
['yield'].transform('median')
所需的样本数据输出:
id date exp d_x yield median_y
1 2/5 3/10 .2 0.01 0.025
1 2/5 3/10 .431 0.04 0.025
1 2/5 3/10 .501 0.05 0.025
1 2/5 3/10 .56 0.1 0.025
1 2/5 3/10 .77 0.05 0.025
2 3/5 4/15 .1 0.012 0.1
2 3/5 4/15 .15 0.1 0.1
2 3/5 4/15 .61 0.2 0.1
2 3/5 4/15 .32 0.12 0.1
2 3/5 4/15 .91 0.05 0.1
答案 0 :(得分:2)
您可以这样做:
df1.query("d_x < .5").groupby(['id', 'date', 'exp'])['yield']\
.agg('median').rename('median_y').reset_index().merge(df1)
使用transform
而不是使用agg
,然后使用merge
返回到分组列上的原始数据框。
输出:
id date exp median_y d_x yield
0 1 2/5 3/10 0.025 0.200 0.010
1 1 2/5 3/10 0.025 0.431 0.040
2 1 2/5 3/10 0.025 0.501 0.050
3 1 2/5 3/10 0.025 0.560 0.100
4 1 2/5 3/10 0.025 0.770 0.050
5 2 3/5 4/15 0.100 0.100 0.012
6 2 3/5 4/15 0.100 0.150 0.100
7 2 3/5 4/15 0.100 0.610 0.200
8 2 3/5 4/15 0.100 0.320 0.120
9 2 3/5 4/15 0.100 0.910 0.050
answer评论:
df1.merge(df1.query("d_x < .5").groupby(['id', 'date', 'exp'])['yield']\
.agg('median').rename('median_y').reset_index())
输出:
id date exp d_x yield median_y
0 1 2/5 3/10 0.200 0.010 0.025
1 1 2/5 3/10 0.431 0.040 0.025
2 1 2/5 3/10 0.501 0.050 0.025
3 1 2/5 3/10 0.560 0.100 0.025
4 1 2/5 3/10 0.770 0.050 0.025
5 2 3/5 4/15 0.100 0.012 0.100
6 2 3/5 4/15 0.150 0.100 0.100
7 2 3/5 4/15 0.610 0.200 0.100
8 2 3/5 4/15 0.320 0.120 0.100
9 2 3/5 4/15 0.910 0.050 0.100
答案 1 :(得分:2)
您可以稍微更改命令以获取所需的输出,如下所示。 (我不知道您编辑过添加新样本。在您的新样本上):
df1['median_y'] = (df1['yield'].where(df1.d_x < .5)
.groupby([df1.id, df1.date, df1.exp])
.transform('median'))
Out[232]:
id date exp d_x yield median_y
0 1 2/5 3/10 0.200 0.010 0.025
1 1 2/5 3/10 0.431 0.040 0.025
2 1 2/5 3/10 0.501 0.050 0.025
3 1 2/5 3/10 0.560 0.100 0.025
4 1 2/5 3/10 0.770 0.050 0.025
5 2 3/5 4/15 0.100 0.012 0.100
6 2 3/5 4/15 0.150 0.100 0.100
7 2 3/5 4/15 0.610 0.200 0.100
8 2 3/5 4/15 0.320 0.120 0.100
9 2 3/5 4/15 0.910 0.050 0.100