从熊猫数据框中的组内选择特定行
Posted
技术标签:
【中文标题】从熊猫数据框中的组内选择特定行【英文标题】:Select particular rows from inside groups in pandas dataframe 【发布时间】:2015-12-03 14:32:20 【问题描述】:假设我有一个如下所示的数据框:
group level
0 1 10
1 1 10
2 1 11
3 2 5
4 2 5
5 3 9
6 3 9
7 3 9
8 3 8
想要的输出是这样的:
group level
0 1 10
5 3 9
也就是说,这就是逻辑:查看每个组的内部,如果level
列中存在多个不同的值,则返回该组中的第一行。例如,没有选择组 2
中的任何行,因为 level
列中存在的唯一值是 5
。
另外,如果我想要最后一行而不是第一行这样的组,情况会如何变化?
我尝试将group_by
语句与从level
列中的条目创建集合相结合,但未能产生任何几乎合理的结果。
【问题讨论】:
【参考方案1】:这可以通过groupby
和apply
在每个组上运行一个简单的函数来完成:
def get_first_val(group):
has_multiple_vals = len(group['level'].unique()) >= 2
if has_multiple_vals:
return group['level'].loc[group['level'].first_valid_index()]
else:
return None
df.groupby('group').apply(get_first_val).dropna()
Out[8]:
group
1 10
3 9
dtype: float64
还有一个last_valid_index()
方法,所以你不必
进行任何重大更改以获取最后一行。
如果您想保留其他列,只需稍作调整:
import numpy as np
df['col1'] = np.random.randint(10, 20, 9)
df['col2'] = np.random.randint(20, 30, 9)
df
Out[17]:
group level col1 col2
0 1 10 19 21
1 1 10 18 24
2 1 11 14 23
3 2 5 14 26
4 2 5 10 22
5 3 9 13 27
6 3 9 16 20
7 3 9 18 26
8 3 8 11 2
def get_first_val_keep_cols(group):
has_multiple_vals = len(group['level'].unique()) >= 2
if has_multiple_vals:
return group.loc[group['level'].first_valid_index(), :]
else:
return None
df.groupby('group').apply(get_first_val_keep_cols).dropna()
Out[20]:
group level col1 col2
group
1 1 10 19 21
3 3 9 13 27
【讨论】:
如何确保其他列得到维护,假设原始数据框有 col1、col2、col3,我仍希望将其保留为结果的一部分? 这神秘地不适用于我。使用以前的方法,我得到了正确的结果,只丢失了一些列,现在我得到了一个空的数据框。也许这里返回 group.loc[group['level'].first_valid_index(), :] without , ?【参考方案2】:这样会更简单:
In [121]:
print df.groupby('group').\
agg(lambda x: x.values[0] if (x.values!=x.values[0]).any() else np.nan).\
dropna()
level
group
1 10
3 9
对于每个组,如果任何值与第一个值不同,则将该组聚合为其第一个值;否则,将其聚合到nan
。
最后,dropna()
。
【讨论】:
以上是关于从熊猫数据框中的组内选择特定行的主要内容,如果未能解决你的问题,请参考以下文章
如何从熊猫数据框中的当前行中减去前一行并将其应用于每一行;不使用循环?