设置:
# create a MultiIndex
dfx = pd.MultiIndex.from_product([
list('ab'),
list('cd'),
list('xyz'),
], names=['idx1', 'idx2', 'idx3'])
# create a dataframe that fits the index
df = pd.DataFrame([None, .9, -.08, -2.11, 1.09, .38, None, None, -.37, -.86, 1.51, -.49], columns=['random_data'])
df.set_index(dfx, inplace=True)
输出:
random_data
idx1 idx2 idx3
a c x NaN
y 0.90
z -0.08
d x -2.11
y 1.09
z 0.38
b c x NaN
y NaN
z -0.37
d x -0.86
y 1.51
z -0.49
在此索引层次结构中,我正在尝试完成以下任务:
[idx1, idx2, idx3]
中缺少值时,用NaN
的组平均值填充[idx1, idx2
][idx1, idx2, idx3]
中缺少多个值时,用NaN
的组平均值填充[idx1]
我已经尝试过df.apply(lambda col: col.fillna(col.groupby(by='idx1').mean()))
作为解决#2的方法,但是我无法使其正常工作。
UPDATE
好,所以我已经部分解决了这个问题,但是仍然对如何有条件地应用这些内容感到困惑:
对于案例1:
df.unstack().apply(lambda col: col.fillna(col.mean()), axis=1).stack()
。
我通过查看此内容验证了正确的值:
df.groupby(by=['idx1', 'idx2']).mean()
,
但是它也替换了我在情况2中试图以不同方式处理的缺失值。
同样适用于#2:
df.unstack().unstack().apply(lambda col: col.fillna(col.mean()), axis=1).stack().stack()
通过查看确认所替换的值是正确的>
df.groupby(by=['idx1']).mean()
但它也适用于情况#1,我不希望。
设置:#创建一个MultiIndex dfx = pd.MultiIndex.from_product([list('ab'),list('cd'),list('xyz'),],names = ['idx1','idx2' ,'idx3'])#创建一个适合索引df = pd的数据框。...
我敢肯定有一种更优雅的方法,但是以下应该可以达到您想要的结果:
IIUC,您可以尝试一下。获取级别mean
的idx1
和级别[mean
,idx1
]的idx2
。 Fillna使用[idx1
,idx2
]的平均值。接下来,使用mask
通过NaN
的mean
分配具有多于1个idx1
的组的行
Sample `df`:
random_data
idx1 idx2 idx3
a c x NaN
y -0.09
z -0.01
d x -1.30
y -0.11
z 1.33
b c x NaN
y NaN
z 0.74
d x -1.44
y 0.50
z -0.61
df1_m = df.mean(level='idx1')
df12_m = df.mean(level=['idx1', 'idx2'])
m = df.isna().groupby(level=['idx1', 'idx2']).transform('sum').gt(1)
df_filled = df.fillna(df12_m).mask(m & df.isna(), df1_m)
Out[110]:
random_data
idx1 idx2 idx3
a c x -0.0500
y -0.0900
z -0.0100
d x -1.3000
y -0.1100
z 1.3300
b c x -0.2025
y -0.2025
z 0.7400
d x -1.4400
y 0.5000
z -0.6100
好,解决了。