如何解决使用就地掩码的工作方式不同吗?
我刚刚发现了面具的这种奇怪行为,有人可以向我解释一下吗?
A) [输入]
df = pd.DataFrame(np.arange(10).reshape(-1,2),columns=['A','B'])
df['C'] ='hi'
df.mask(df[['A','B']]<3,inplace=True)
[输出]
A | B | C | |
---|---|---|---|
0 | NaN | NaN | 嗨 |
1 | NaN | 3.0 | 嗨 |
2 | 4.0 | 5.0 | 嗨 |
3 | 6.0 | 7.0 | 嗨 |
4 | 8.0 | 9.0 | 嗨 |
乙) [输入]
df = pd.DataFrame(np.arange(10).reshape(-1,'B']]<3)
[输出]
A | B | C | |
---|---|---|---|
0 | NaN | NaN | NaN |
1 | NaN | 3.0 | NaN |
2 | 4.0 | 5.0 | NaN |
3 | 6.0 | 7.0 | NaN |
4 | 8.0 | 9.0 | NaN |
提前致谢
解决方法
不同结果的根本原因是您传递的布尔数据帧与要屏蔽的数据帧的形状不同。 df.mask()
用 inplace
的值填充缺失的部分。
从源代码中,您可以看到 pandas.DataFrame.mask() 在内部调用 pandas.DataFrame.where()。 pandas.DataFrame.where()
然后调用 _where() 方法替换条件为 False 的值。
我只是以df.where()
为例,下面是示例代码:
import numpy as np
import pandas as pd
df = pd.DataFrame(np.arange(12).reshape(-1,3),columns=['A','B','C'])
df1 = df.where(df[['A','B']]<3)
df.where(df[['A','B']]<3,inplace=True)
在本例中,df
是
A B C
0 0 1 2
1 3 4 5
2 6 7 8
3 9 10 11
df[['A','B']]<3
,cond
参数的值,是
A B
0 True True
1 False False
2 False False
3 False False
深入研究 _where()
方法,following lines 是关键部分:
def _where(...):
# align the cond to same shape as myself
cond = com.apply_if_callable(cond,self)
if isinstance(cond,NDFrame):
cond,_ = cond.align(self,join="right",broadcast_axis=1)
...
# make sure we are boolean
fill_value = bool(inplace)
cond = cond.fillna(fill_value)
由于 cond
和 df
的形状不同,cond.align()
用 NaN
值填充缺失值。之后,cond
看起来像
A B C
0 True True NaN
1 False False NaN
2 False False NaN
3 False False NaN
然后使用 cond.fillna(fill_value)
,将 NaN
值替换为 inplace
值。所以 C 列的值与 inplace
值相同。
尽管仍有一些代码(L9048 和 L9124-L9145)与 inplace
相关。我们不需要关心细节,因为这些行的目的是替换条件为 False 的值。
回忆一下 df
是
A B C
0 0 1 2
1 3 4 5
2 6 7 8
3 9 10 11
-
df1=df.where(df[['A','B']]<3)
:cond
C 列是 False,因为inplace
的默认值为 False。执行df.where()
后,df
C 列设置为other
参数的值,默认情况下为NaN
。 -
df.where(df[['A',inplace=True)
:cond
C 列为 True。执行df.where()
后,df
C列保持不变。
# print(df1)
A B C
0 0.0 1.0 NaN
1 NaN NaN NaN
2 NaN NaN NaN
3 NaN NaN NaN
# print(df) after df.where(df[['A',inplace=True)
A B C
0 0.0 1.0 2
1 NaN NaN 5
2 NaN NaN 8
3 NaN NaN 11
,
想的很简单。
df = pd.DataFrame(np.arange(10).reshape(-1,2),'B'])
df['C'] ='hi'
df.mask(df[['A','B']]<3)
最后一行代码要求提供完整的数据帧 (df.
)。条件已应用于列 ['A','B']
,因此,一旦列 'C' 不是条件的一部分,它将为列 NaN
返回 C
。
下面的内容与 df.mask(df[['A','B']]<3)
>>> df[["A","B","C"]].mask(df[['A','B']]<3)
A B C
0 NaN NaN NaN
1 NaN 3.0 NaN
2 4.0 5.0 NaN
3 6.0 7.0 NaN
4 8.0 9.0 NaN
>>>
而且,df.mask(df[['A','C']]<3)
会产生错误,因为 'C' 列是字符串类型
TypeError: '<' not supported between instances of 'str' and 'int'
最后,只返回列 "A" and "B"
>>> df[["A","B"]].mask(df[['A','B']]<3)
A B
0 NaN NaN
1 NaN 3.0
2 4.0 5.0
3 6.0 7.0
4 8.0 9.0
当您应用要完成的命令 inplace
时,它不会对列 C
执行任何操作,因为 NaN 在 mask
方法中将是“什么都不做”>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。