Pandas Dataframe:获取组内每个子组的第一行的平均值
Posted
技术标签:
【中文标题】Pandas Dataframe:获取组内每个子组的第一行的平均值【英文标题】:Pandas Dataframe: get average of first rows of each subgroup within a group 【发布时间】:2020-09-07 11:29:04 【问题描述】:我有一个如下所示的 pandas 数据框:
df = pd.DataFrame('Person_ID': [1,1,1,1,1,1,2,2,2,3,3,3,3],
'Item_ID': [1,1,2,4,4,4,2,3,3,1,2,2,2],
'Value': [1,4,6,5,8,7,3,2,9,8,4,1,2])
我想按 person_id 和 item_id 分组,然后得到第一行的平均值。例如:Person_ID 1 与 'Item_ID's 1,2 和 4 “关联”。此 Person_ID 和这些组的第一个条目的值分别是 1,6 和 5。平均为 4。
Person_ID Item_ID Value
0 1 1 1
1 1 1 4
2 1 2 6
3 1 4 5
4 1 4 8
5 1 4 7
6 2 2 3
7 2 3 2
8 2 3 9
9 3 1 8
10 3 2 4
11 3 2 1
12 3 2 2
期望的结果:
Person_ID Average_value_first_entries
1 4
2 2.5
3 6
我注意到这个问题很相似,但是这个问题的一个更复杂的版本: Pandas dataframe get first row of each group 在这种情况下,我不想按一个“id”分组,而是按两个“id”分组并取平均值。
我尝试了以下方法:
df.groupby(['Person_ID', 'Item_ID']).first()['Value']
但是,这会返回每个“第一个”条目,而不是平均值。
Person_ID Item_ID
1 1 1
2 6
4 5
2 2 3
3 2
3 1 8
2 4
Name: Value, dtype: int64
任何帮助将不胜感激。我将特别感谢“计算高效”(时间)解决方案,因为真实数据集包含 120 万行。
【问题讨论】:
【参考方案1】:找出Person_ID
和Item_ID
的每组first
行后,您需要再次对Person_ID
进行分组以求均值。像这样:
In [1312]: d = df.groupby(['Person_ID','Item_ID'], as_index=False).head(1)
In [1315]: d.groupby('Person_ID', as_index=False)['Value'].mean()
Out[1315]:
Person_ID Value
0 1 4.0
1 2 2.5
2 3 6.0
按照@Datanovice 的建议,或者在一行中:
In [1320]: df.groupby(['Person_ID','Item_ID']).first().groupby(level=0)['Value'].mean().to_frame().reset_index()
Out[1320]:
Person_ID Value
0 1 4.0
1 2 2.5
2 3 6.0
【讨论】:
【参考方案2】:我们可以drop_duplicates
df.drop_duplicates(['Person_ID','Item_ID']).groupby(['Person_ID']).Value.mean()
Person_ID
1 4.0
2 2.5
3 6.0
Name: Value, dtype: float64
【讨论】:
【参考方案3】:我们可以将groupby 与unstack 结合起来
(df.groupby(['Person_ID','Item_ID'])
.first()
.unstack()
.mean(1)
.reset_index(name='Average_value_first_entries')
)
Person_ID Average_value_first_entries
0 1 4.0
1 2 2.5
2 3 6.0
【讨论】:
虽然此代码包含重命名“输出列”的行很有用,但我发现与其他解决方案相比,这种方法的鲁棒性稍差。在实际数据框中,我有许多其他列(与此问题无关);需要调整上面的代码以选择正确的 ('Value') 列;例如:df[['Person_ID','Item_ID', 'Value']].groupby(['Person_ID','Item_ID']).first().unstack().mean(1).reset_index(name='Average_value_first_entries')
以上是关于Pandas Dataframe:获取组内每个子组的第一行的平均值的主要内容,如果未能解决你的问题,请参考以下文章
Pandas:从另一个 df 创建一个新的 df,包含组内的特定值
通过添加其他横截面将 pandas MultiIndex 的横截面设置为 DataFrame
获取 Pandas DataFrame 列中字符串列表中的所有行 - 此模式具有匹配组