将 "NaN" 值替换为具有列多索引 (df.fillna) 的数据框中仅一列的最后一个有效值

Replace "NaN" value by last valid value for only one column in a dataframe with column multi-index (df.fillna)

我正在使用 Python 3.6.5.

这是一个小脚本,用于生成具有一些 "NaN" 值的多索引数据框。

import pandas as pd
import numpy as np

att_1 = ['X', 'Y']
att_2 = ['a', 'b']

df_1 = pd.DataFrame(np.random.randint(10,19,size=(5, 2)), columns=att_2, 
index=[10,20,30,35,40])
df_2 = pd.DataFrame(np.random.randint(20,29,size=(5, 2)), columns=att_2, 
index=[20,25,40,50,80])

# Concat df with new key dimension for column attribute
df = pd.concat([df_1, df_2], keys=att_1, axis=1)

我得到这个数据框

print(df)
       X           Y      
       a     b     a     b
10  17.0  17.0   NaN   NaN
20  15.0  11.0  20.0  28.0
25   NaN   NaN  23.0  24.0
30  12.0  16.0   NaN   NaN
35  10.0  10.0   NaN   NaN
40  15.0  14.0  25.0  28.0
50   NaN   NaN  22.0  22.0
80   NaN   NaN  23.0  21.0

我想将 "NaN" 值替换为最后一个有效值,但仅限于一列。例如,我想得到这个(对于名为 'X'、'b' 的列)

print(df)
       X           Y      
       a     b     a     b
10  17.0  17.0   NaN   NaN
20  15.0  11.0  20.0  28.0
25   NaN  11.0  23.0  24.0
30  12.0  16.0   NaN   NaN
35  10.0  10.0   NaN   NaN
40  15.0  14.0  25.0  28.0
50   NaN  14.0  22.0  22.0
80   NaN  14.0  23.0  21.0

我试过了:

# Replace NaN value by last valid value for column named 'X','b'
df['X']['b'].fillna(method='ffill', inplace=True)

但是我得到这个错误"A value is trying to be set on a copy of a slice from a DataFrame"

对于具有多列索引的数据框,我找不到任何解决方案。 我发现这个 link 让我没有希望。 (https://pandas.pydata.org/pandas-docs/version/0.22/generated/pandas.MultiIndex.fillna.html)

有没有人可以帮助我?

经过一些挖掘,我发现有一种更合适的方式来引用我们想要专门编辑的列。检查 How to deal with SettingWithCopyWarning in Pandas? out for more info. Another resource: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

建议我们使用.loc来修改列。使用下面的行删除了所有错误。

df.loc[df['X']['b'].isnull(), ('X', 'b')] = df['X']['b'].ffill()

但是,这里我使用列的最大值来替换每个 NaN 。我不确定最后一个有效值是什么意思。