python - 使用另一个多索引系列屏蔽数据框
问题描述
我有一个数据框,我想用多索引系列的布尔值屏蔽(转换为 NaN),其中系列的多索引也是数据框中的列名。例如,如果df
是:
df = pd.DataFrame({ 'A': (188, 750, 1330, 1385, 188, 750, 810, 1330, 1385),
'B': (1, 2, 4, 5, 1, 2, 3, 4, 5),
'C': (2, 5, 7, 2, 5, 5, 3, 7, 2),
'D': ('foo', 'foo', 'foo', 'foo', 'bar', 'bar', 'bar', 'bar', 'bar') })
A B C D
0 188 1 2 foo
1 750 2 5 foo
2 1330 4 7 foo
3 1385 5 2 foo
4 188 1 5 bar
5 750 2 5 bar
6 810 3 3 bar
7 1330 4 7 bar
8 1385 5 2 bar
多索引系列ser
是:
arrays = [('188', '750', '810', '1330', '1385'),
('1', '2', '3', '4', '5')]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['A', 'B'])
ser = pd.Series([False, False, True, False, True], index=index)
A B
188 1 False
750 2 False
810 3 True
1330 4 False
1385 5 True
dtype: bool
我如何屏蔽(转换为 NaN)条目在 Series 中的列C
上的值,以便以最终的 Dataframe 结束,如下所示:df
False
ser
A B C D
0 188 1 2 foo
1 750 2 5 foo
2 1330 4 7 foo
3 1385 5 NaN foo
4 188 1 5 bar
5 750 2 5 bar
6 810 3 NaN bar
7 1330 4 7 bar
8 1385 5 NaN bar
解决方案
更改初始化步骤ser
:
arrays = [('188', '750', '810', '1330', '1385'),
('1', '2', '3', '4', '5')]
# Note: The change is in this step - make the levels numeric.
tuples = list(zip(*map(pd.to_numeric, arrays)))
index = pd.MultiIndex.from_tuples(tuples, names=['A', 'B'])
ser = pd.Series([False, False, True, False, True], index=index)
初始化index
的级别以具有与“A”和“B”相同的 dtype。希望这不应该是一个问题。
这将使我们使用loc
基于索引的选择和分配来构建一个更简单的解决方案。
u = df.set_index(['A', 'B'])
u.loc[ser.index[ser], 'C'] = np.nan
u.reset_index()
A B C D
0 188 1 2.0 foo
1 750 2 5.0 foo
2 1330 4 7.0 foo
3 1385 5 NaN foo
4 188 1 5.0 bar
5 750 2 5.0 bar
6 810 3 NaN bar
7 1330 4 7.0 bar
8 1385 5 NaN bar
如果您遇到给定ser
并需要更改索引的 dtype 的情况,您可以使用内部的列表推导快速重新构建它pd.Index.set_levels
。
ser.index = ser.index.set_levels([l.astype(int) for l in ser.index.levels])
# Alternative,
# ser.index = ser.index.set_levels([
# pd.to_numeric(l) for l in ser.index.levels])
现在,这有效:
u = df.set_index(['A', 'B'])
u.loc[ser.index[ser], 'C'] = np.nan
u.reset_index()
A B C D
0 188 1 2.0 foo
1 750 2 5.0 foo
2 1330 4 7.0 foo
3 1385 5 NaN foo
4 188 1 5.0 bar
5 750 2 5.0 bar
6 810 3 NaN bar
7 1330 4 7.0 bar
8 1385 5 NaN bar
注意 中的ser.index[ser]
索引步骤loc
,我们使用ser
' 索引而不是index
直接。
推荐阅读
- node.js - Docker容器在运行时抛出错误
- apache-nifi - Nifi 通过进程组传递属性
- php - 提交 CI 表单时没有任何反应
- google-cloud-firestore - 了解分布式系统中的一致性
- angularjs - AngularJS - 如何为带有业力和茉莉花的异步功能编写单元测试?
- php - 使用查询字符串进行分页会导致找不到错误页面
- c# - 如何为 WCF http 中继配置负载均衡策略
- bash - shell脚本正在运行,但不是脚本内的命令
- laravel - 无法在 laravel 控制器的变量中获取文件名和扩展名?
- php - 如何在没有 id 的情况下更新表