python - inplace=True doesn't work for subset data
问题描述
I am trying to fill missing values in subset of rows. I am using inplace=True
in fillna()
, but it is not working in jupyter notebook. You can see attached picture showing NaN in the first 2 rows in column of Surface. I am not sure why?
I have to do this so it is working. why? Thank you for your help.
data.loc[mark,'Surface']=data.loc[mark,'Surface'].fillna(value='TEST')
Here are my codes
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)
This one is working:
data.loc[mark,'Surface']=data.loc[mark,'Surface'].fillna(value='TEST')
解决方案
您在这里遇到的主要问题是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
因此,上述两种方法都不会返回原始数据的“视图”,这就是执行inplace
操作不会更改原始数据帧的原因。为了从您返回视图,.loc
您需要使用切片作为行索引。
>>> df.loc[10:15, "Surface"]._is_view
True
现在这仍然无法解决您的问题,因为您填写的值NaN
可能会或可能不会更改dtype
“表面”列的值。在我设置的示例中,“Surface”具有 float64 dtype-并且通过填写NaN
值“Test”,您将强制该 dtype 更改与原始数据帧不兼容。如果您的“Surface”列是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
.. ... ...
TLDR;一般不要依赖inplace
熊猫。在其大部分操作中,它仍然会创建基础数据的副本,然后尝试用新副本替换原始源。Pandas 的内存效率不高,因此如果您担心内存性能,您可能希望切换到像Vaex这样从头开始设计为零拷贝的东西,而不是尝试通过 pandas。
您分配数据帧切片的方法是最合适的,并将确保您收到尽可能“就地”更新数据帧的正确结果:
>>> df.loc[bool_mask, "Surface"] = df.loc[bool_mask, "Surface"].fillna("Test")
推荐阅读
- typo3 - 如何仅显示选择字段中的记录,这些记录在 TYPO3 的某个 storagePid 中?
- android-studio - Appium 与 Android 模拟器代理问题
- acumatica - 使用 _ 事件表示法调用 Acumatica 事件的委托
- jenkins - Jenkins:hudson.AbortException:TEST 的实例计划 CPU 值无效
- elasticsearch - 使用 refresh=wait_for 的 Elasticsearch 并发索引请求
- ios - 视图控制器不尊重“largeTitleDisplayMode”
- google-sheets - Filter function for Google Sheets - dynamic cell reference
- python - 当切换到其他分支或从终端运行黑色时,Vim 不显示更改
- kubernetes - 遵循使用 Lets Encrypt 的教程后,无法在 EKS 的应用程序网关中公开 HTTPS
- pine-script - 我想为买入条件编写代码:最近 5 个柱的收盘价一直在上涨