代码之家  ›  专栏  ›  技术社区  ›  Kang

Python数据框架:用单索引列组合/替换多索引列

  •  0
  • Kang  · 技术社区  · 6 年前

    我的df中有多个索引列。在我的df中,表示布尔值的所有值都是1或0。我的任务是用另一个df\U测试数据帧中的值替换值“1”。见下文。

    In [221]: df
    Out[221]:
    first        bar                 baz
    second       one       two       one       two
    0            0         1         0         0
    1            1         0         1         1
    2            0         0         0         1
    3            0         0         0         0
    4            1         1         1         1
    ..............(continues)
    

    我的df\u测试有规则的列(不是多索引)和应该进入df的值。

    In [222]: df_test
    Out[222]:
            amount
    0            38
    1            2179   
    2            191     
    3            4     
    4            19823    
    ..............(continues)
    

    两个数据帧匹配和我的输出的索引应为:

    In [223]: df
    Out[223]:
    first        bar                 baz
    second       one       two       one       two
    0            0         38        0         0
    1            2179      0         2179      2179      
    2            0         0         0         191     
    3            0         0         0         0
    4            19823     19823     19823     19823    
    ..............(continues)
    

    请注意,我的df可以没有像index=3这样的“1”值,也可以有像index=4这样的所有“1”值。如果有有效的方法来设置我的数据帧

    2 回复  |  直到 6 年前
        1
  •  2
  •   cs95    6 年前

    要获得结果,可以使用广播乘法-

    v = df.values * df_test.amount.values[:, None]
    
    v
    array([[    0,    38,     0,     0],
           [ 2179,     0,  2179,  2179],
           [    0,     0,     0,   191],
           [    0,     0,     0,     0],
           [19823, 19823, 19823, 19823]])
    

    要恢复原始数据帧,只需调用 DataFrame 建造师-

    df = pd.DataFrame(v, columns=df.columns, index=df.index)
    df
    
    first     bar           baz       
    second    one    two    one    two
    0           0     38      0      0
    1        2179      0   2179   2179
    2           0      0      0    191
    3           0      0      0      0
    4       19823  19823  19823  19823
    

    从piRSquared's借来的感谢设置 answer .

        2
  •  2
  •   piRSquared    6 年前

    您要使用 pd.DataFrame.mask 并使用列 amount 作为替代品。但是,您需要提供 axis=0 参数,告诉熊猫在索引上对齐。

    df.mask(df.eq(1), df_test.amount, axis=0)
    
    first     bar           baz       
    second    one    two    one    two
    0           0     38      0      0
    1        2179      0   2179   2179
    2           0      0      0    191
    3           0      0      0      0
    4       19823  19823  19823  19823
    

    安装程序

    df = pd.DataFrame(
        [[0, 1, 0, 0],
         [1, 0, 1, 1],
         [0, 0, 0, 1],
         [0, 0, 0, 0],
         [1, 1, 1, 1]],
        columns=pd.MultiIndex.from_product(
            [['bar', 'baz'], ['one', 'two']],
            names=['first', 'second']
        )
    )
    
    df_test = pd.DataFrame(dict(amount=[38, 2179, 191, 4, 19823]))