如何通过仅考虑特定行来使用分组计算中位数

时间:2019-06-14 09:44:07

标签: python pandas

我有以下数据框:

df = pd.DataFrame({'A': [1, 2, 3, 4, 1, 2, 3, 4], 
                   'B': [1, 1, 1, 1, 2, 2, 2, 2],
                   'C': [np.nan, 1, 3, 5, 6, 2, np.nan, np.nan]})
   A  B    C
0  1  1  NaN
1  2  1  1.0
2  3  1  3.0
3  4  1  5.0
4  1  2  6.0
5  2  2  2.0
6  3  2  NaN
7  4  2  NaN

随之而来的是以下地图:

df_map = pd.DataFrame({'A': [1, 1, 2, 2, 3, 3, 4, 4],
                       'N': [2, 3, 1, 4, 2, 1, 3, 1]})
   A  N
0  1  2
1  1  3
2  2  1
3  2  4
4  3  2
5  3  1
6  4  3
7  4  1

我想用NaN定义的每个组的mean填充B值,但只考虑A对应于{{1}的行}在N中。

例如:

df_map在索引NaN处将用0的平均值填充,因为[1.0, 3.0]指向1

结果数据框应如下所示:

[2, 3]

谢谢!

2 个答案:

答案 0 :(得分:3)

希望有人可以修复它,使其更优雅一些,但这应该可以使用多个mergemap的组合来达到您想要的:

fill_map = (df.merge(df_map, on='A')
            .merge(df, left_on=['B', 'N'], right_on=['B', 'A'], suffixes=('', '_'))
            .groupby(['B', 'A'])['C_'].mean())


df['C'] = df['C'].fillna(df[['B', 'A']].apply(tuple, axis=1).map(fill_map))

[出]

   A  B    C
0  1  1  2.0
1  2  1  1.0
2  3  1  3.0
3  4  1  5.0
4  1  2  6.0
5  2  2  2.0
6  3  2  4.0
7  4  2  6.0

答案 1 :(得分:1)

您还可以通过应用如下函数来解决它:

def func(x):
    return np.nanmean( df[ df['A'].isin( df_map[df_map.A==x['A']].N.values) & (df.B==x.B)].C)

df.loc[df.C.isna(), 'C'] = df.apply(func, axis=1)

输出:

   A  B    C
0  1  1  2.0
1  2  1  1.0
2  3  1  3.0
3  4  1  5.0
4  1  2  6.0
5  2  2  2.0
6  3  2  4.0
7  4  2  6.0