pandas 如果某列值重复,并且另一列满足条件,则删除一行

bq9c1y66  于 2023-05-12  发布在  其他
关注(0)|答案(2)|浏览(141)

我有一个DataFrame,我想在其中删除一行(或多行),其中多个连续行具有基于不同列的值的列的相同值。在本例中,如果B为高,我希望保留B中具有最高值的行,如果B为低,则保留具有最低值的行。从本质上讲,我试图只有高,其次是低和低的高。

df = pd.DataFrame({'A': ['low', 'high', 'high', 'low', 'low','low'],                   
                   'B': [10, 70, 90, 40, 50,60]})

输出:

A     B
0   low   10
1   high  70
2   high  90
3   low   40
4   low   50
5   low   60

期望:

A     B
0   low   10
2   high  90
3   low   40

试图让我的头周围如何实现的逻辑,并已撞上了砖墙。

ecfsfe2w

ecfsfe2w1#

这里是另一种方法:

d = {'low':-1}

(df.assign(B = df['B'].mul(df['A'].map(d),fill_value=1))
 .groupby(['A',pd.Series(pd.factorize(df['A'])[0]).diff().ne(0).cumsum()]).max()
 .abs()
 .sort_index(level=1)
 .droplevel(1)
 .reset_index())

df.loc[df['A'].map({'low':-1}).mul(df['B'],fill_value=1).groupby(df['A'].ne(df['A'].shift()).cumsum()).idxmax()]

输出:

A     B
0   low  10.0
1  high  90.0
2   low  40.0
dsekswqp

dsekswqp2#

下面是一个使用groupby.apply的快速而肮脏的方法:

out = (df.groupby(['A', df['A'].ne(df['A'].shift()).cumsum()])
       .apply(lambda x: x.max() if x['A'].iat[0]=='high' else x.min())
       .droplevel(0).sort_index().reset_index(drop=True))

另一种方法可以是先找到groupby + max;然后mask“低”值,并用groupby + min值替换它们:

g = df.groupby(['A', df['A'].ne(df['A'].shift()).cumsum()], sort=False)['B']
out = g.max().mask(lambda x: x.index.get_level_values(0)=='low', g.min()).droplevel(1).reset_index()

输出:

A   B
0   low  10
1  high  90
2   low  40

相关问题