Wen*_*ndy 19 python group-by pandas pandas-groupby
我按 A 列对我的数据集进行分组,然后想取 B 列中的最小值和 C 列中的相应值。
data = pd.DataFrame({'A': [1, 2], 'B':[ 2, 4], 'C':[10, 4]})
data
A B C
0 1 4 3
1 1 5 4
2 1 2 10
3 2 7 2
4 2 4 4
5 2 6 6
Run Code Online (Sandbox Code Playgroud)
我想得到:
A B C
0 1 2 10
1 2 4 4
Run Code Online (Sandbox Code Playgroud)
目前我按 A 分组,并创建一个值来指示我将保留在我的数据集中的行:
a = data.groupby('A').min()
a['A'] = a.index
to_keep = [str(x[0]) + str(x[1]) for x in a[['A', 'B']].values]
data['id'] = data['A'].astype(str) + data['B'].astype('str')
data[data['id'].isin(to_keep)]
Run Code Online (Sandbox Code Playgroud)
我相信有一种更直接的方法可以做到这一点。我在这里看到了很多使用多索引的答案,但我想这样做而不向我的数据帧添加多索引。感谢您的帮助。
cs9*_*s95 27
感觉你多虑了 只需使用groupby和idxmin:
df.loc[df.groupby('A').B.idxmin()]
A B C
2 1 2 10
4 2 4 4
Run Code Online (Sandbox Code Playgroud)
df.loc[df.groupby('A').B.idxmin()].reset_index(drop=True)
A B C
0 1 2 10
1 2 4 4
Run Code Online (Sandbox Code Playgroud)
小智 14
有类似的情况,但具有更复杂的列标题(例如“B val”),在这种情况下需要:
df.loc[df.groupby('A')['B val'].idxmin()]
Run Code Online (Sandbox Code Playgroud)
您可以sort_values并且drop_duplicates:
df.sort_values('B').drop_duplicates('A')
Run Code Online (Sandbox Code Playgroud)
输出:
A B C
2 1 2 10
4 2 4 4
Run Code Online (Sandbox Code Playgroud)
接受的答案(建议idxmin)不能与管道模式一起使用。管道友好的替代方案是首先对值进行排序,然后使用groupbywith DataFrame.head:
data.sort_values('B').groupby('A').apply(DataFrame.head, n=1)
Run Code Online (Sandbox Code Playgroud)
这是可能的,因为默认情况下groupby 会保留每个组中行的顺序,这是稳定且有记录的行为(请参阅 参考资料pandas.DataFrame.groupby)。
这种方法还有其他好处:
.sort_values(),例如:
data.sort_values(['final_score', 'midterm_score']).groupby('year').apply(DataFrame.head, n=1)
Run Code Online (Sandbox Code Playgroud)
与其他答案一样,为了完全匹配问题中所需的结果.reset_index(drop=True),需要制作最终的片段:
df.sort_values('B').groupby('A').apply(DataFrame.head, n=1).reset_index(drop=True)
Run Code Online (Sandbox Code Playgroud)