熊猫:根据多个列的值删除或更改特定的行

时间:2019-05-23 11:43:31

标签: python pandas

我在元组和值列表之间有一个字典,例如:

ExoPlayer

元组表示熊猫{ ('book1', 'US'): [1, 5], ('book2', 'CA'): [3] } 中的列值(也可能有其他列),而列表表示同一数据帧中单个列中的值。
假设我的数据框看起来像这样:

DataFrame

我想删除上面 book country value 0 book1 US 1 1 book1 US 9 2 book1 US 5 3 book2 MX 7 4 book2 CA 3 5 book1 CA 1 代表的行,或者将这些行的值更改为0。
因此结果将是:

dict

或者:

    book country  value
0  book1      US      0
1  book1      US      9
2  book1      US      0
3  book2      MX      7
4  book2      CA      0
5  book1      CA      1

执行此操作的最佳方法是什么?
我想在相当大的数据框上执行此操作,它应该尽可能高效。

我的想法是做这样的事情,但是效率不高(由于存在多个 book country value 0 book1 US 9 1 book2 MX 7 2 book1 CA 1 ),我得到了重复的行而不是删除了行。 (我不想使用loc,因为一开始我可能不想删除重复项)

drop_duplicates

1 个答案:

答案 0 :(得分:2)

您可以通过Index.isinboolean indexing创建元组列表并检查成员资格:

d = {
    ('book1', 'US'): [1, 5],
    ('book2', 'CA'): [3]
}

tups = [k + (x, ) for k, v in d.items() for x in v]

df = df[~df.set_index(['book','country','value']).index.isin(tups)]
print (df)
    book country  value
1  book1      US      9
3  book2      MX      7
5  book1      CA      1

对于根据条件设置的0,请使用loc

df.loc[df.set_index(['book','country','value']).index.isin(tups), 'value'] = 0
print (df)
    book country  value
0  book1      US      0
1  book1      US      9
2  book1      US      0
3  book2      MX      7
4  book2      CA      0
5  book1      CA      1

另一种解决方案:

tups = [k + (x, ) for k, v in d.items() for x in v]

df1 = pd.DataFrame(tups, columns=['book','country','value'])

df2 = pd.concat([df, df1, df1], ignore_index=True)
df = df2[~df2.duplicated(keep=False)]
print (df)
    book country  value
1  book1      US      9
3  book2      MX      7
5  book1      CA      1