在pandas数据框中进行分组和去重

3
我有一个如下的pandas数据框。我想基于所有三个列进行分组,保留具有Col1最大值的组。
import pandas as pd
df = pd.DataFrame({'col1':['A', 'A', 'A', 'A', 'B', 'B'], 'col2':['1', '1', '1', '1', '2', '3'], 'col3':['5', '5', '2', '2', '2', '3']})
df


  col1 col2 col3
0   A   1    5
1   A   1    5
2   A   1    2
3   A   1    2
4   B   2    2
5   B   3    3

我期望的输出结果

  col1 col2 col3
0   A   1    5
1   A   1    5
4   B   2    2
5   B   3    3

我尝试了以下代码,但它返回每个组的最后一行,而我想按col3排序并保留具有最大col3值的组。
df.drop_duplicates(keep='last', subset=['col1','col2','col3'])


  col1  col2 col3
1   A   1     5
3   A   1     2
4   B   2     2
5   B   3     3

例如:这里我想要放弃第一组,因为2 < 5,所以我想保留col3值为5的组。
df.sort_values(by=['col1', 'col2', 'col3'], ascending=False)
a_group = df.groupby(['col1', 'col2', 'col3'])
for name, group in a_group:
  group = group.reset_index(drop=True)
  print(group)

  col1 col2 col3
0    A    1    2
1    A    1    2
  col1 col2 col3
0    A    1    5
1    A    1    5
  col1 col2 col3
0    B    2    2
  col1 col2 col3
0    B    3    3

1
您期望的输出有重复,第二行是否是指 '1' 和 '2'? - Yefet
我的期望输出是我想要的,我想保留具有col3最大值的组。 - Shanoo
您希望保留索引吗?还是您不介意最终得到一个新的索引? - sophocles
不关心索引 - Shanoo
4个回答

4

如果您希望保留的列具有不同的值,则无法在所有列上进行分组。相反,不要将该列包含在分组中,考虑其他列:

col_to_max = 'col3'
i = df.columns ^ [col_to_max]
out = df[df[col_to_max] == df.groupby(list(i))[col_to_max].transform('max')]

print(out)

  col1 col2 col3
0    A    1    5
1    A    1    5
4    B    2    2
5    B    3    3

2
所以我们可以这样做。
out = df[df.col3==df.groupby(['col1','col2'])['col3'].transform('max')]
  col1 col2 col3
0    A    1    5
1    A    1    5
4    B    2    2
5    B    3    3

1
我相信你可以使用groupbynlargest(2)。同时确保你的'col3'是一个数字列。
>>> df['col3'] = df['col3'].astype(int)
>>> df.groupby(['col1','col2'])['col3'].nlargest(2).reset_index().drop('level_2',axis=1)

  col1 col2  col3
0    A    1     5
1    A    1     5
2    B    2     2
3    B    3     3

1
你可以获取没有 col3 最大值和重复索引的 index 并删除交集。
ind = df.assign(max = df.groupby("col1")["col3"].transform("max")).query("max != col3").index
ind2 = df[df.duplicated(keep=False)].index

df.drop(set(ind).intersection(ind2))

  col1 col2 col3
0    A    1    5
1    A    1    5
4    B    2    2
5    B    3    3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接