Python 熊猫赢了';t fillna()到位

Python 熊猫赢了';t fillna()到位,python,pandas,dataframe,Python,Pandas,Dataframe,我试图在数据帧中的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 361

我试图在数据帧中的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)
<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)
给我:

<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)
<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)

INT64索引:1542个条目,0到3611
数据列(共7列):
NPI 1103非空值
引脚1542非空值
PROV FIRST 1541非空值
PROV LAST 1542非空值
PROV MID 1316非空值
规格NM 1541非空值
标志439非空值
数据类型:float64(2)、int64(1)、object(4)
这只是一排,但仍然令人沮丧。我做错了什么?

您正在填写一份副本(然后您就看不到了)

要么:

  • 不要
    fillna
    inplace(原地做某事不会提高性能)
比如说

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)
  • 首先将副本分配给一个新变量(a_n6[[list_of_fileds]]是多数据类型对象中的副本),请参见此处:
这里有一个更深入的解释

使用
dict
作为
参数,以
fillna()
正如@rhkarls对@Jeff答案的评论中所提到的,使用索引到列列表的
.loc
将不支持
in place
操作,我也感到沮丧。这里有一个解决办法

例如:

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
假设我们只想为
x
y
填写
a
b

我希望使用
.loc
能起作用(如在作业中),但事实并非如此,如前所述:

# doesn't work
df.loc[:,['x','y']].fillna(0, inplace=True)
print(df) # nothing changed
但是,
fillna()
value
参数可以是:

或者是一个dict/Series/DataFrame值,指定每个索引(对于系列)或列(对于数据帧)使用哪个值。(不在dict/Series/DataFrame中的值将不被填充)

事实证明,使用价值观的dict是可行的:

# 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结果保存在另一个变量中,并按如下方式重新分配:

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的解决方法,顶部的答案给了我设置了CopyWarning:试图在数据帧的切片副本上设置值,所以这就是我最终得到的结果。它工作正常,不会发出任何警告:

fill_dict = {x: 0 for x in columns_of_interest}
df.loc[:, columns_of_interest].fillna(fill_dict, inplace=True)
“使用dict作为值参数”的答案对我来说并不适用,但一个简单的解决方法是使用:

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

我还遇到了一些函数,其中
inplace=True
似乎被忽略。虽然在您的案例中,这不是问题所在,但在排除故障时值得记住。我认为inplace参数应该防止它填充副本。如果不改变函数的行为,
inplace
arg的作用是什么?那么为什么inplace甚至允许fillna()?如果使用.loc,inplace将起作用。如果你正在复印,Inplace不应该工作。查看Jeff包含的链接。它不适用于字段列表(例如df.loc[:,[list of fields]]),但适用于切片或单个字段。关于这方面的详细信息,请参见。我刚刚在20Gb的数据集上运行了fillna,带有inplace,并出现了“未实现”错误。我没有看到“没有绩效提升”的咆哮。我没有另一个20Gb内存来进行临时拷贝。原地踏步将非常有益。