python - 用 numpy 数组与 DataFrame 屏蔽 pandas DataFrame
问题描述
我想使用 2D 布尔掩码选择性地更改pandas
DataFrame
. 我注意到我不能(成功)使用numpy
数组作为掩码,但我可以使用DataFrame
. 然而,更令人沮丧的是,我没有得到这个numpy
方法的错误。
例如,
df = pd.DataFrame({'A':[1,2,3,4],
'B':[10,20,30,40]})
mask_np = np.array([[True,True],
[False,False],
[True,False],
[False,True]])
mask_pd = pd.DataFrame(mask_np, columns=['A','B'])
我认为任何一个掩码都会返回掩码所在位置的df
值True
。但相反,df[mask_np]
产生
A B
0 1 10
0 1 10
2 3 30
3 4 40
这不是我所期望的,我也无法解释。另一方面, df[mask_pd]
产生
A B
0 1.0 10.0
1 NaN NaN
2 3.0 NaN
3 NaN 40.0
这是我期望和想要的。
为什么我不能使用numpy
面膜?我的互联网搜索结果没有任何相关性。这种差异背后的任何解释将不胜感激!
[pandas
版本0.20.3;Python 3.6.3]
解决方案
源代码说明了原因。该__getitem__
方法[]
是语法糖,专门检查通过数据帧的索引:
elif isinstance(key, DataFrame):
return self._getitem_frame(key)
如果数据帧是布尔类型,则调用的_getitem_frame
方法将返回:pd.DataFrame.where
def _getitem_frame(self, key):
if key.values.size and not is_bool_dtype(key.values):
raise ValueError('Must pass DataFrame with boolean values only')
return self.where(key)
NumPy 数组所采用的路线_getitem_array
是不同的,而且更加复杂。出于某种原因,该代码旨在以不同方式处理 NumPy / Pandas 输入,而不是确保相同数据类型的一致性。
使用 Pandas 数据框的常规布尔索引通常沿轴应用,即通过行/轴 0df.loc[mask, :]
或列/轴 1 通过df.loc[:, mask]
。
请注意,为了清楚起见,您可以并且可能应该pd.DataFrame.where
直接访问:
res = df.where(mask_np)
print(res)
A B
0 1.0 10.0
1 NaN NaN
2 3.0 NaN
3 NaN 40.0
推荐阅读
- flutter - 如何将小部件嵌入图像并将其保存到设备
- java - 使用 Apache POI HSSF 在 Excel 中存储 ArrayList
- laravel - Laravel 更新单列
- python - 生成所有连续子数组的算法
- networking - K8s中不同集群中的Pod之间使用yaml进行通信
- python - Python OpenGL 不会加载纹理
- javascript - 这个方法 object.keys 是返回一个数组还是保留一个对象
- javascript - 使用 React App 在 Firestore 中切换布尔值
- java - SwingWorker - 在没有 Swing-Gui 的情况下的替代方案
- javascript - 编译后未定义 Webpack 自定义库