【问题标题】:Multi-column replacement in Pandas based on row selectionPandas 中基于行选择的多列替换
【发布时间】:2016-03-22 17:07:00
【问题描述】:

关于如何在DataFrame 中选择行并替换这些行中的列中的值,关于 SO 存在大量问题,但缺少一个用例。以DataFramefrom this question为例,

In [1]: df
Out[1]:
  apple banana cherry
0     0      3   good
1     1      4    bad
2     2      5   good

如果想要根据另一列更改单个列,这很有效:

df.loc[df.cherry == 'bad', 'apple'] = df.banana * 2

或者这样设置两列中的值:

df.loc[df.cherry == 'bad', ['apple', 'banana'] = np.nan

但这不起作用:

df.loc[df.cherry == 'bad', ['apple', 'banana'] = [df.banana, df.apple]

,因为显然右边是3x2,而左边是1x2,所以报错

ValueError: Must have equal len keys and value when setting with an ndarray

所以我明白问题出在哪里,但解决办法是什么?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    IIUC 你可以试试:

    df['a'] = df.apple * 3
    df['b'] = df.banana * 2
    print df
       apple  banana cherry  a   b
    0      0       3   good  0   6
    1      1       4    bad  3   8
    2      2       5   good  6  10
    
    df[['a', 'b']] = df.loc[df.cherry == 'bad', ['apple', 'banana']] 
    print df
       apple  banana cherry    a    b
    0      0       3   good  NaN  NaN
    1      1       4    bad  1.0  4.0
    2      2       5   good  NaN  NaN
    

    或者使用values的条件:

    df['a'] = df.apple * 3
    df['b'] = df.banana * 2
    
    df.loc[df.cherry == 'bad', ['apple', 'banana']] = 
    df.loc[df.cherry == 'bad', ['a', 'b']].values
    print df
       apple  banana cherry  a   b
    0      0       3   good  0   6
    1      3       8    bad  3   8
    2      2       5   good  6  10
    

    原始列的另一个选项:

    print df[['apple','banana']].shift() * 2
       apple  banana
    0    NaN     NaN
    1   12.0     6.0
    2    2.0     8.0
    
    df.loc[df.cherry == 'bad', ['apple', 'banana']] = df[['apple','banana']].shift() * 2
    print df
       apple  banana cherry
    0    6.0     3.0   good
    1   12.0     6.0    bad
    2    2.0     5.0   good
    

    【讨论】:

    • 谢谢!第二种解决方案是我正在寻找的解决方案。所以基本上就我而言,它将是df.loc[df.cherry == 'bad', ['apple', 'banana']] = df.loc[df.cherry == 'bad', ['banana', 'apple']].values。有趣的是,如果没有values,它就无法工作,即使我倒置了列名。无论如何,还有一个问题:如果我想要一些特别的东西(例如df.banana * 2),有没有办法不向df 添加新列?也许apply
    • 谢谢,看起来不错——所以基本上我可以像df.loc[...] = pd.concat([df.banana * 3, df.apple * 2], axis=1).values 那样做某事。显然,价值观是我一直在寻找的灵丹妙药,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    • 2020-05-18
    • 2019-04-10
    • 1970-01-01
    相关资源
    最近更新 更多