根据条件从pandas系列中删除重复项

Lea*_*ner 2 python python-3.x pandas

我有一个熊猫系列:

    increased   1.691759
    increased   1.601759
    reports     1.881759
    reports     1.491759
    president   1.386294
    president   1.791759
    exclusive   1.381759
    exclusive   1.291759
    bank        1.386294
    bank        1.791759
    ........    ........
    ........    .......
Run Code Online (Sandbox Code Playgroud)

我只想从系列中删除重复的单词,并保留具有更高数值的单词.所以,预期产量,

increased   1.691759
reports     1.881759
president   1.791759
exclusive   1.381759
bank        1.791759
........    ........
........    .......
Run Code Online (Sandbox Code Playgroud)

我通过将一个系列转换为pandas数据帧来尝试它,它运行正常.但是,由于我有大型系列,这将是一个耗时的过程.所以,我只想在现有系列中处理.

sac*_*cuL 5

您可以drop_duplicates在排序后使用col2.默认情况下,删除重复项会保留第一个,因此如果排序方式col2使得最大值是第一个,则它将保持最大值:

df.sort_values('col2', ascending=False).drop_duplicates('col1')

        col1      col2
2    reports  1.881759
5  president  1.791759
9       bank  1.791759
0  increased  1.691759
6  exclusive  1.381759
Run Code Online (Sandbox Code Playgroud)

替代使用groupbytail:

另一种方法是这样做:

df.sort_values('col2').groupby('col1').tail(1)

        col1      col2
6  exclusive  1.381759
0  increased  1.691759
5  president  1.791759
9       bank  1.791759
2    reports  1.881759
Run Code Online (Sandbox Code Playgroud)

编辑:根据您的评论,要转换为系列以供进一步使用,您可以执行以下操作:

df.sort_values('col2', ascending=False).drop_duplicates('col1').set_index('col1')['col2']

col1
reports      1.881759
president    1.791759
bank         1.791759
increased    1.691759
exclusive    1.381759
Name: col2, dtype: float64
Run Code Online (Sandbox Code Playgroud)

或直接在系列上做一个groupby(但这个更慢,参见基准测试):

s.sort_values().groupby(s.index).tail(1)
Run Code Online (Sandbox Code Playgroud)

基准

我用Series1000000的长度测试了它,即使将它转换为数据帧并返回到系列,也只需不到一秒钟.你可能能够找到一种更快的方式而不需要改造,但这并不是很糟糕的IMO

df = pd.DataFrame({'col1':np.random.choice(['increased', 'reports', 'president', 'exclusive', 'bank'], 1000000), 'col2':np.random.randn(1000000)})

s = pd.Series(df.set_index('col1').col2)

>>> s.head()
col1
president    0.600691
increased    1.752238
president   -1.409425
bank         0.349149
reports      0.596207
Name: col2, dtype: float64
>>> len(s)
1000000

import timeit

def test(s = s):
    return s.to_frame().reset_index().sort_values('col2', ascending=False).drop_duplicates('col1').set_index('col1')['col2']

>>> timeit.timeit(test, number=10) / 10
0.685569432300008
Run Code Online (Sandbox Code Playgroud)

groupby直接在系列上应用会变慢:

def gb_test(s=s):
    return s.sort_values().groupby(s.index).tail(1)

>>> timeit.timeit(gb_test, number=10) / 10
0.7673859989999983
Run Code Online (Sandbox Code Playgroud)