numpy Python -删除列表中包含的 Dataframe 行(不使用循环)

nkhmeac6  于 2023-01-26  发布在  Python
关注(0)|答案(5)|浏览(135)

问题说明

我有一个包含两列'A''B'的 Dataframe 。我还有一个元组列表,其中元组的第一个元素是列'A'中的元素,第二个元素是列'B'中的元素。我想删除 Dataframe 中与元组重合的所有行。
当然,我可以只使用一个循环,但我想要一个更聪明的解决方案,将是更快和更干净。

最小工作示例

import pandas as pd
df = pd.DataFrame(
    {
        'A': ['a', 'b', 'c', 'd', 'a', 'd', 'a', 'c'],
        'B': [4, 2, 2, 1, 3, 4, 3, 2],
    }
)
rows_to_remove = [('a', 4), ('c', 2), ('d', 4), ('a', 3)]
fslejnso

fslejnso1#

我会使用 * boolean索引 * 和pandas.Series.isin

m = df.agg(tuple, axis=1).isin(rows_to_remove)

df = df.loc[~m]

输出:

print(df)

   A  B
1  b  2
3  d  1
cunj1qz1

cunj1qz12#

您可以使用带指示灯的merge

out = (df.merge(pd.DataFrame(rows_to_remove, columns=['A', 'B']), indicator=True, how='left')
         .query('_merge == "left_only"')
         #.drop(columns='_merge') # commented to see the logic
       )

输出:

A  B     _merge
1  b  2  left_only
3  d  1  left_only

或者,与drop结合使用:

idx = (df.merge(pd.DataFrame(rows_to_remove, columns=['A', 'B']), how='left', indicator=True)
         .query('_merge == "both"').index
      )

out = df.drop(idx)

输出:

A  B
1  b  2
3  d  1
b4lqfgs4

b4lqfgs43#

如果您import numpy as np,您可以:

df[~(df.values==np.array(rows_to_remove, dtype=object)[:,None]).any(0).all(-1)]

它很有趣,但也很有用,因为我在谷歌colab上测试,性能是274 µs ± 11.6 µs1.44 ms ± 37.7µs从@永恒的解决方案,我认为是最好的,这是同一个来到我的脑海中,只要我读到的问题。
看看更大的DataFrame的区别会很有趣。

vsnjm48y

vsnjm48y4#

您可以从rows_to_remove创建一个 Dataframe ,然后附加到原始 Dataframe 并删除重复项:

>>> (pd.concat([df, pd.DataFrame(rows_to_remove, columns=['A', 'B'])])
       .drop_duplicates(['A', 'B'], keep=False))

   A  B
1  b  2
3  d  1
hfyxw5xn

hfyxw5xn5#

希望这能有所帮助。你可以使用'df.drop'按索引删除行/列。请看下面提到的:
数据框架.drop(标签=无、*、轴=0、索引=无、列=无、级别=无、位置=False、错误=“引发”)[https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.drop.html]

相关问题