我正在尝试在字符串/对象类型的数据框中的4个特定列上填充“”。我可以将这些列分配给一个新的变量,就像我的fillna(),但是当我在fillna()inplace中时,底层数据不会改变。
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)
这只是一排,但仍令人沮丧。我做错了什么?
答案 0 :(得分:17)
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
仅x
和y
,不 a
和b
我希望使用.loc
工作(如在作业中),但它没有,如前所述:
# doesn't work
df.loc[:,['x','y']].fillna(0, inplace=True)
print(df) # nothing changed
但是,documentation表示value
的{{1}}参数可以是:
交替显示值的dict / Series / DataFrame,指定每个索引(对于Series)或列(对于DataFrame)使用哪个值。 (不会在dict / Series / DataFrame中填充的值)。
事实证明,使用值的字典将起作用:
fillna()
此外,如果您的子集中有很多列,则可以使用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
答案 1 :(得分:7)
您正在填写一份副本(您无法看到)
或者:
fillna
到位(在场内做某事不会带来任何性能提升)a_n6[[list_of_fileds]]
是多重型对象中的副本),请参见此处:http://pandas.pydata.org/pandas-docs/stable/indexing.html#returning-a-view-versus-a-copy 这是一个更深入的解释 Pandas: Chained assignments
答案 2 :(得分:0)
一种解决方法是将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的变通方法
答案 3 :(得分:0)
最重要的答案是给我SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame
,所以这就是我的最终目的。它有效,并且不发出任何警告:
fill_dict = {x: 0 for x in columns_of_interest}
df.loc[:, columns_of_interest].fillna(fill_dict, inplace=True)
答案 4 :(得分:0)
“使用dict作为值参数”答案对我不起作用,但使用以下简单方法即可:
for n in ["PROV LAST", "PROV FIRST", "PROV MID", "SPEC NM"]:
a_n6[n].fillna("", inplace=True)
a_n6