使用就地掩码的工作方式不同吗?

JeB*_*JeB 12 python mask series dataframe pandas

我刚刚发现了面具的这种奇怪行为,有人可以向我解释一下吗?

A) [输入]

df = pd.DataFrame(np.arange(10).reshape(-1, 2), columns=['A', 'B'])
df['C'] ='hi'
df.mask(df[['A', 'B']]<3, inplace=True)
Run Code Online (Sandbox Code Playgroud)

[输出]

一种 C
0 NaN NaN 你好
1 NaN 3.0 你好
2 4.0 5.0 你好
3 6.0 7.0 你好
4 8.0 9.0 你好

B) [输入]

df = pd.DataFrame(np.arange(10).reshape(-1, 2), columns=['A', 'B'])
df['C'] ='hi'
df.mask(df[['A', 'B']]<3)
Run Code Online (Sandbox Code Playgroud)

[输出]

一种 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

先感谢您

Ynj*_*jmh 5

不同结果的根本原因是您传递的布尔数据帧与要屏蔽的数据帧的形状不同。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)
Run Code Online (Sandbox Code Playgroud)

在这个例子中,df

   A   B   C
0  0   1   2
1  3   4   5
2  6   7   8
3  9  10  11
Run Code Online (Sandbox Code Playgroud)

df[['A', 'B']]<3,参数的值cond

       A      B
0   True   True
1  False  False
2  False  False
3  False  False
Run Code Online (Sandbox Code Playgroud)

深入研究_where()方法,以下几行是关键部分:

   A   B   C
0  0   1   2
1  3   4   5
2  6   7   8
3  9  10  11
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

然后使用cond.fillna(fill_value)NaN将这些值替换为 的值inplace。所以C列与value具有相同的值inplace

尽管仍有一些代码(L9048L9124-L9145)与inplace. 我们不需要关心细节,因为这些行的目的是替换条件为 False 的值。

回想一下,df

   A   B   C
0  0   1   2
1  3   4   5
2  6   7   8
3  9  10  11
Run Code Online (Sandbox Code Playgroud)
  • df1=df.where(df[['A', 'B']]<3)condC 列为 False,因为 的默认值为inplaceFalse。执行完后df.where(), C 列将设置为默认参数df的值。otherNaN
  • df.where(df[['A', 'B']]<3, inplace=True)condC 列为 True。完成后df.where()dfC列保持不变。
# 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', 'B']]<3, inplace=True)
     A    B   C
0  0.0  1.0   2
1  NaN  NaN   5
2  NaN  NaN   8
3  NaN  NaN  11
Run Code Online (Sandbox Code Playgroud)