A B
1 10
1 20
2 30
2 40
3 10
应该变成这样:
A B
1 20
2 40
3 10
我猜可能有一种简单的方法来做到这一点——也许只需在删除重复项之前对DataFrame进行排序,但我不太了解groupby的内部逻辑,不能想出来。您有什么建议吗?
A B
1 10
1 20
2 30
2 40
3 10
应该变成这样:
A B
1 20
2 40
3 10
我猜可能有一种简单的方法来做到这一点——也许只需在删除重复项之前对DataFrame进行排序,但我不太了解groupby的内部逻辑,不能想出来。您有什么建议吗?
这会获取最后一个,但不是最大值:
In [10]: df.drop_duplicates(subset='A', keep="last")
Out[10]:
A B
1 1 20
3 2 40
4 3 10
你也可以这样做:
In [12]: df.groupby('A', group_keys=False).apply(lambda x: x.loc[x.B.idxmax()])
Out[12]:
A B
A
1 1 20
2 2 40
3 3 10
cols
和take_last
参数已被弃用,现已被subset
和keep
参数所取代。http://pandas.pydata.org/pandas-docs/version/0.17.1/generated/pandas.DataFrame.drop_duplicates.html - JezzamonFutureWarning: take_last=True 关键字已被弃用,请使用 keep='last'
。 - tumultous_roosterdf.sort_values(by=['B']).drop_duplicates(subset=['A'], keep='last')
的原因?我的意思是,这个 sort_values 对我来说似乎很安全,但我不知道它是否真的安全。 - Little Bobby Tablesgroup_by
中有多列的情况下,可以添加.reset_index(drop=True)
。
df.groupby(['A','C'], group_keys=False).apply(lambda x: x.ix[x.B.idxmax()]).reset_index(drop=True)
这将重置索引,因为其默认值将是由'A'
和'C'
组成的Multindex。 - Hamri Said顶部答案正在做过多的工作,对于较大的数据集来说速度非常慢。apply
很慢,如果可能的话应该避免使用。ix
已被弃用,也应该避免使用。
df.sort_values('B', ascending=False).drop_duplicates('A').sort_index()
A B
1 1 20
3 2 40
4 3 10
或者只需按所有其他列分组,并获取您需要的列的最大值。 df.groupby('A', as_index=False).max()
lambda
函数来进行概括。例如,我如何仅删除小于重复值平均值的值。 - Dexter最简单的解决方案:
根据一个列删除重复项:
df = df.drop_duplicates('column_name', keep='last')
根据多个列删除重复项:
df = df.drop_duplicates(['col_name1','col_name2','col_name3'], keep='last')
我会先按照 B 列降序排列数据框,然后根据 A 列去重并保留第一个。
df = df.sort_values(by='B', ascending=False)
df = df.drop_duplicates(subset='A', keep="first")
没有任何分组
试试这个:
df.groupby(['A']).max()
我被一篇重复的问题的链接带到这里。
对于只有两列,做以下操作是否更简单:
df.groupby('A')['B'].max().reset_index()
如果要保留整个行(即使有多个列),可以这样做:
df.loc[df.groupby(...)[column].idxmax()]
['A', 'B']
组的'C'
取最大值的完整行,我们可以执行以下操作:out = df.loc[df.groupby(['A', 'B')['C'].idxmax()]
当群组较少(即有很多重复项)时,此方法比使用drop_duplicates()
解决方案更快(排序量更小):
设置:
n = 1_000_000
df = pd.DataFrame({
'A': np.random.randint(0, 20, n),
'B': np.random.randint(0, 20, n),
'C': np.random.uniform(size=n),
'D': np.random.choice(list('abcdefghijklmnopqrstuvwxyz'), size=n),
})
sort_index()
):%timeit df.loc[df.groupby(['A', 'B'])['C'].idxmax()].sort_index()
# 101 ms ± 98.7 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit df.sort_values(['C', 'A', 'B'], ascending=False).drop_duplicates(['A', 'B']).sort_index()
# 667 ms ± 784 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
最简单的方法:
# First you need to sort this DF as Column A as ascending and column B as descending
# Then you can drop the duplicate values in A column
# Optional - you can reset the index and get the nice data frame again
# I'm going to show you all in one step.
d = {'A': [1,1,2,3,1,2,3,1], 'B': [30, 40,50,42,38,30,25,32]}
df = pd.DataFrame(data=d)
df
A B
0 1 30
1 1 40
2 2 50
3 3 42
4 1 38
5 2 30
6 3 25
7 1 32
df = df.sort_values(['A','B'], ascending =[True,False]).drop_duplicates(['A']).reset_index(drop=True)
df
A B
0 1 40
1 2 50
2 3 42
我认为在你的情况下,你并不真正需要使用groupby。我建议按照B列的降序排序,然后在A列上去重,如果需要,还可以给它们一个新的漂亮、干净的索引:
df.sort_values('B', ascending=False).drop_duplicates('A').sort_index().reset_index(drop=True)
这里有一个我必须解决的变化,值得分享:对于columnA
中的每个唯一字符串,我想找到与之关联的最常见字符串在columnB
中。
df.groupby('columnA').agg({'columnB': lambda x: x.mode().any()}).reset_index()
.any()
如果模式相同,则选择其中一个。(请注意,在int
序列上使用.any()
会返回布尔值而不是其中一个。)
对于原始问题,相应的方法简化为
df.groupby('columnA').columnB.agg('max').reset_index()
。
你也可以尝试这个
df.drop_duplicates(subset='A', keep='last')
我是从 https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.drop_duplicates.html 引用的