替换多索引

时间:2016-11-04 21:26:50

标签: python pandas

我正在使用pandas并将一些数据加载到数据帧中。我想要做的是替换我的数据中的场景频率列,除了每组中的第一个值之外的所有列。

我的数据如下:

ExplosionID  FireWater  FireID    Scenario Frequency
111          0          213       4.209055e-15
                        214       4.209055e-15
                        215       4.209055e-15
                        217       4.209055e-15
                        219       4.209055e-15
                        220       4.209055e-15
112          0          232       8.388742e-16
                        233       8.388742e-16
                        234       8.388742e-16
                        235       8.388742e-16
                        237       8.388742e-16
                        239       8.388742e-16
                        240       8.388742e-16

我想将场景频率列中除第一个值之外的所有值替换为0,以便最终得到:

ExplosionID  FireWater  FireID    Scenario Frequency
111          0          213       4.209055e-15
                        214       0
                        215       0
                        217       0
                        219       0
                        220       0
112          0          232       8.388742e-16
                        233       0
                        234       0
                        235       0
                        237       0
                        239       0
                        240       0

前三列(ExplosionIFireWaterFireID)是多索引中的索引。

我已经定义了一个功能:

#function to replace all but first value in group with 0
def replace_all_except_first(group):
    group.iloc[1:] = 0
    return group

并尝试了以下内容:

data_to_sum = HL_df_subset.groupby(level=0).apply(replace_all_except_first)

其中HL_df_subset是我的数据框。但是,这会将所有值都设置为0。

我是python的新手,我知道我完全误解了groupby的工作方式,但我一直在努力尝试各种各样的工作。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

  • cumcount :查找订购。创建一个不等于0的布尔系列。这意味着,而不是第一行
  • mask :获取true值并屏蔽数据框的相关部分。在这种情况下,它使得每个人的数量都不是np.nan的零。
  • fillna :抓住np.nan并填充零
HL_df_subset.mask(HL_df_subset.groupby(level=0).cumcount().ne(0)).fillna(0)

考虑df

df = pd.DataFrame(
    dict(A=np.arange(100, 116)),
    pd.MultiIndex.from_product(
        [list('ab'), list('xy'), [1, 2, 3, 4]]))
df

         A
a x 1  100
    2  101
    3  102
    4  103
  y 1  104
    2  105
    3  106
    4  107
b x 1  108
    2  109
    3  110
    4  111
  y 1  112
    2  113
    3  114
    4  115
df.mask(df.groupby(level=[0, 1]).cumcount().ne(0)).fillna(0)

           A
a x 1  100.0
    2    0.0
    3    0.0
    4    0.0
  y 1  104.0
    2    0.0
    3    0.0
    4    0.0
b x 1  108.0
    2    0.0
    3    0.0
    4    0.0
  y 1  112.0
    2    0.0
    3    0.0
    4    0.0