我正在尝试填充行子集中的缺失值。我正在使用inplace=True
in fillna()
,但它在 jupyter notebook 中不起作用。您可以在 Surface 列的前 2 行中看到显示 NaN 的附加图片。我不知道为什么?
我必须这样做,所以它正在工作。为什么?感谢您的帮助。
data.loc[mark,'Surface']=data.loc[mark,'Surface'].fillna(value='TEST')
Run Code Online (Sandbox Code Playgroud)
这是我的代码
mark=(data['Pad']==51) | (data['Pad']==52) | (data['Pad']==53) | (data['Pad']==54) | (data['Pad']==55)
data.loc[mark,'Surface'].fillna(value='TEST',inplace=True)
Run Code Online (Sandbox Code Playgroud)
这个正在工作:
data.loc[mark,'Surface']=data.loc[mark,'Surface'].fillna(value='TEST')
Run Code Online (Sandbox Code Playgroud)
您在这里遇到的主要问题是pandas
没有非常明确的视图与复制规则。您的结果向我表明这里的问题.loc
是返回副本而不是视图。虽然 pandas 确实尝试从 返回视图.loc
,但有很多注意事项。
在玩了一会儿之后,似乎使用布尔/位置索引掩码返回一个副本 - 您可以使用私有_is_view
属性验证这一点:
import pandas as pd
import numpy as np
df = pd.DataFrame({"Pad": range(40, 60), "Surface": np.nan})
print(df)
Pad Surface
0 40 NaN
1 41 NaN
2 42 NaN
. ... ...
19 59 NaN
# Create masks
bool_mask = df["Pad"].isin(range(51, 56))
positional_mask = np.where(bool_mask)[0]
# Check `_is_view` after simple .loc:
>>> df.loc[bool_mask, "Surface"]._is_view
False
>>> df.loc[positional_mask, "Surface"]._is_view
False
Run Code Online (Sandbox Code Playgroud)
因此,上述两种方法都没有返回原始数据的“视图”,这就是执行inplace
操作不会更改原始数据帧的原因。为了从.loc
您那里返回视图,您需要使用切片作为行索引。
>>> df.loc[10:15, "Surface"]._is_view
True
Run Code Online (Sandbox Code Playgroud)
现在这仍然无法解决您的问题,因为您填充的值NaN
可能会或可能不会更改dtype
“表面”列的 。在我设置的示例中,“Surface”有一个 float64 dtype- 并且通过填充NaN
值“Test”,您将强制该 dtype 更改,这与原始数据帧不兼容。如果您的“表面”列是object
dtype,那么您无需担心这一点。
>>> df.dtypes
Pad int64
Surface float64
# this does not work because "Test" is incompatible with float64 dtype
>>> df.loc[10:15, "Surface"].fillna("Test", inplace=True)
# this works because 0.9 is an appropriate value for a float64 dtype
>>> df.loc[10:15, "Surface"].fillna(0.9, inplace=True)
>>> print(df)
Pad Surface
.. ... ...
8 48 NaN
9 49 NaN
10 50 0.9
11 51 0.9
12 52 0.9
13 53 0.9
14 54 0.9
15 55 0.9
16 56 NaN
17 57 NaN
.. ... ...
Run Code Online (Sandbox Code Playgroud)
TLDR;一般不要依赖inplace
熊猫。在其大部分操作中,它仍会创建底层数据的副本,然后尝试用新副本替换原始数据源。Pandas 的内存效率不高,所以如果你担心内存性能,你可能想切换到像Vaex这样从头开始设计为零复制的东西,而不是试图通过Pandas。
您分配数据帧切片的方法是最合适的,并且将确保您收到将数据帧更新为“就地”的正确结果:
>>> df.loc[bool_mask, "Surface"] = df.loc[bool_mask, "Surface"].fillna("Test")
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
49 次 |
最近记录: |