python - Pandas:根据多列值删除或更改特定行
问题描述
我在元组到值列表之间有一个字典,例如:
{
('book1', 'US'): [1, 5],
('book2', 'CA'): [3]
}
元组表示 pandas 中的列值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
我想删除dict
上面表示的行或将这些行的值更改为 0。
所以结果将是:
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
这样做的最佳方法是什么?
我想在一个非常大的数据帧上执行此操作,它应该尽可能高效。
我的想法是做这样的事情,但它似乎不是很有效(由于 multiple loc
),我得到重复行而不是删除行。(我不想使用drop_duplicates
,因为一开始可能有我不想删除的重复项)
data_frame.set_index(['book', 'country'], inplace=True)
for key, values in rows_to_remove.iteritems():
data_frame.loc[key] = data_frame.loc[key][~data_frame.loc[key]['value'].isin(values)]
data_frame.reset_index(inplace=True)
解决方案
Index.isin
您可以通过以下方式创建元组列表并检查成员资格boolean 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
推荐阅读
- version - 什么是正确的第一个版本?0.1.0 或 0.0.1 还是其他?
- java - 如何在java中触发静态代码的执行?
- postgresql - PostgreSQL:从多行中选择结果,汇总结果并返回单行
- apache-servicemix - 服务组合更新网页
- php - AJAX 表单提交仅适用于第一次提交
- html - Bootstrap 4:在自定义 div 内的容器内垂直居中内容
- c++ - make_pair 和花括号 { } 在 C++ 中分配一对的区别?
- javascript - 如何在 Angular 中使用使用 commonjs、browserify 和 gulp 创建的消费节点包
- flutter - 如何使小部件与父级匹配但也具有最大宽度?
- python - 停止递归函数 Python