Pandas不会飞入

2024-04-27 18:15:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在数据帧中的4个特定列(字符串/对象类型)上用“”填充NAs。我可以将这些列作为I fillna()分配给一个新变量,但当I fillna()插入时,基础数据不会更改。

a_n6 = a_n6[["PROV LAST", "PROV FIRST", "PROV MID", "SPEC NM"]].fillna("")
a_n6

给我:

<class 'pandas.core.frame.DataFrame'>
Int64Index: 1542 entries, 0 to 3611
Data columns (total 4 columns):
PROV LAST     1542  non-null values
PROV FIRST    1542  non-null values
PROV MID      1542  non-null values
SPEC NM       1542  non-null values
dtypes: object(4)

但是

a_n6[["PROV LAST", "PROV FIRST", "PROV MID", "SPEC NM"]].fillna("", inplace=True)
a_n6

给我:

<class 'pandas.core.frame.DataFrame'>
Int64Index: 1542 entries, 0 to 3611
Data columns (total 7 columns):
NPI           1103  non-null values
PIN           1542  non-null values
PROV FIRST    1541  non-null values
PROV LAST     1542  non-null values
PROV MID      1316  non-null values
SPEC NM       1541  non-null values
flag          439  non-null values
dtypes: float64(2), int64(1), object(4)

只是一排,但仍然令人沮丧。我做错什么了?


Tags: columns数据pandasnullclassfirstlastvalues
3条回答

使用dict作为value参数来fillna()

正如@rhkarls在评论@Jeff的答案时提到的,使用索引到列列表的.loc将不支持inplace操作,我也觉得这很令人沮丧。这是一个解决办法。

示例:

import pandas as pd
import numpy as np

df = pd.DataFrame({'a':[1,2,3,4,np.nan],
                   'b':[6,7,8,np.nan,np.nan],
                   'x':[11,12,13,np.nan,np.nan],
                   'y':[16,np.nan,np.nan,19,np.nan]})
print(df)
#     a    b     x     y
#0  1.0  6.0  11.0  16.0
#1  2.0  7.0  12.0   NaN
#2  3.0  8.0  13.0   NaN
#3  4.0  NaN   NaN  19.0
#4  NaN  NaN   NaN   NaN

假设我们想fillna仅用于xy不用于ab

我希望使用.loc来工作(如在任务中),但它不是,如前所述:

# doesn't work
df.loc[:,['x','y']].fillna(0, inplace=True)
print(df) # nothing changed

然而,documentation表示,fillna()value参数可以是:

alternately a dict/Series/DataFrame of values specifying which value to use for each index (for a Series) or column (for a DataFrame). (values not in the dict/Series/DataFrame will not be filled).

事实证明,使用一个dict of values将起作用:

# works
df.fillna({'x':0, 'y':0}, inplace=True)
print(df)
#     a    b     x     y
#0  1.0  6.0  11.0  16.0
#1  2.0  7.0  12.0   0.0
#2  3.0  8.0  13.0   0.0
#3  4.0  NaN   0.0  19.0
#4  NaN  NaN   0.0   0.0

此外,如果您的子集中有很多列,则可以使用dict理解,如:

df.fillna({x:0 for x in ['x','y']}, inplace=True) # also works

你正在填写一份副本(然后你看不到)

或者:

  • 不要fillna就地(就地做某事不会提高性能)

例如

a_n6[["PROV LAST", "PROV FIRST", "PROV MID", "SPEC NM"]] = a_n6[["PROV LAST", "PROV FIRST", "PROV MID", "SPEC NM"]].fillna("")

或者最好

a_n6.fillna({'PROV LAST': '', 'PROV FIRST': '',
            'PROV MID': '', 'SPEC NM': ''}, inplace=True)

这里有一个更深入的解释 Pandas: Chained assignments

解决方法是将fillna结果保存到另一个变量中,然后按如下方式重新分配:

na_values_filled = X.fillna(0)
X = na_values_filled

我的确切例子(我不能去工作,否则)是一个案例,我想在每个小组的第一行填写。像这样:

groups = one_train.groupby("installation_id")
first_indexes_filled = one_train.loc[groups.apply(pd.DataFrame.first_valid_index), 'clicks'].fillna(0)
one_train.loc[groups.apply(pd.DataFrame.first_valid_index), 'clicks'] =  first_indexes_filled

我的情况可能不必要地复杂,但我认为一般的“保存结果,然后重新分配”方法应该作为解决inplace=True失败的方法

相关问题 更多 >