熊猫GroupBy使用另一种热编码/重叠蒙版的DataFrame

时间:2019-01-10 17:08:01

标签: python pandas dataframe group-by pandas-groupby

我有两个数据框,分别观察行和列的特征(或组成员资格),例如:

> data_df

     a    b    c
A    1    2    1
B    0    1    3
C    0    0    1
D    2    1    1
E    1    1    1

> mask_df

    g1   g2
A    0    1
B    1    0
C    1    0
D    1    0
E    0    1

我想根据第二个数据帧(data_df)中的二进制值(掩码)对第一个数据帧(mask_df)中的值进行分组和汇总(总计)。结果应为以下内容(组x个特征):

> aggr_df

     a    b    c
g1   2    2    5
g2   2    3    2

在熊猫中,是否有一种方法可以通过单个命令使用包含在第二个数据帧(data_df)中的掩码将第一个数据帧(mask_df)分组?

5 个答案:

答案 0 :(得分:2)

您可以使用dotgroupby廉价地做到这一点:

data_df.groupby(mask_df.dot(mask_df.columns)).sum()

    a  b  c
g1  2  2  5
g2  2  3  2

在哪里

mask_df.dot(mask_df.columns)

A    g2
B    g1
C    g1
D    g1
E    g2
dtype: object

假设每一行始终将1设置为一列,则效果很好。

答案 1 :(得分:2)

请注意,即使在第一个数据帧(# STEP 1: split NumPy arrays into separate columns col1 = pd.DataFrame(df1.pop('col1').values.tolist()).add_prefix('col1_') col2 = pd.DataFrame(df1.pop('col2').values.tolist()).add_prefix('col2_') df1 = df1.join(pd.concat([col1, col2], axis=1)) # STEP 2: calculate indices for NumPy assignment x_idx = np.arange(df1.shape[0])[:, None] y_idx = df1.iloc[:, :4].values.argsort(1) # STEP 3: assign via iloc df1.iloc[:, 4:] = df1.iloc[:, 4:].values[x_idx, y_idx] print(df1) # col1_0 col1_1 col1_2 col1_3 col2_0 col2_1 col2_2 col2_3 # 0 1 4 3 2 0 5 4 1 # 1 9 10 7 5 103 102 100 101 # 2 100 120 10 22 12 13 10 11 )中的观测值属于第二个数据帧(data_df)中的多个掩码的情况下,此方法也将起作用。

mask_df

答案 2 :(得分:1)

执行此操作的最佳方法是合并数据帧。您可以先使用join语句在索引上进行合并。 df_merge = data_df.merge(aggr_df, left_on=True, right_on=True)。然后,您可以仅使用df_merge进行分组操作。

答案 3 :(得分:1)

这是一种使用列表理解的方法:

pd.DataFrame([(data_df.T * mask_df[i]).sum(axis=1) for i in mask_df.columns], 
             index = mask.columns)

    a  b  c
g1  2  2  5
g2  2  3  2

答案 4 :(得分:1)

我决定再写一个答案,因为:

  • coldspeed的答案仅适用于一键编码
  • W-B的答案不容易并行化,因为它基于字典理解

就我而言,我注意到仅将mask_dfdata_df一起使用点积就可以达到相同的结果:

> mask_df.T.dot(data_df)

在获取平均值而不是总和的特殊情况下,这可以通过将mask_df按每组的数目缩放来实现:

> mask_df.T.dot(data_df).div(mask_df.sum(), axis=0)