【问题标题】:Update row values where certain condition is met in pandas更新熊猫中满足特定条件的行值
【发布时间】:2016-08-22 22:34:51
【问题描述】:

假设我有以下数据框:

更新 featanother_feat 列的值的最有效方法是什么/strong>?

是这个吗?

for index, row in df.iterrows():
    if df1.loc[index,'stream'] == 2:
       # do something

更新: 如果我有超过 100 列怎么办?我不想明确命名要更新的列。我想将每列的值除以 2(流列除外)。

所以要明确我的目标是什么:

将所有具有流 2 的行的所有值除以 2,但不更改流列

【问题讨论】:

    标签: python pandas indexing iterator mask


    【解决方案1】:

    您可以对.ix 执行相同的操作,如下所示:

    In [1]: df = pd.DataFrame(np.random.randn(5,4), columns=list('abcd'))
    
    In [2]: df
    Out[2]: 
              a         b         c         d
    0 -0.323772  0.839542  0.173414 -1.341793
    1 -1.001287  0.676910  0.465536  0.229544
    2  0.963484 -0.905302 -0.435821  1.934512
    3  0.266113 -0.034305 -0.110272 -0.720599
    4 -0.522134 -0.913792  1.862832  0.314315
    
    In [3]: df.ix[df.a>0, ['b','c']] = 0
    
    In [4]: df
    Out[4]: 
              a         b         c         d
    0 -0.323772  0.839542  0.173414 -1.341793
    1 -1.001287  0.676910  0.465536  0.229544
    2  0.963484  0.000000  0.000000  1.934512
    3  0.266113  0.000000  0.000000 -0.720599
    4 -0.522134 -0.913792  1.862832  0.314315
    

    编辑

    在额外信息之后,以下将返回所有列 - 满足某些条件 - 值减半:

    >> condition = df.a > 0
    >> df[condition][[i for i in df.columns.values if i not in ['a']]].apply(lambda x: x/2)
    

    【讨论】:

    • 如果我没有很多列这是可行的,我应该说我有100多个列。
    • 我用condition = (df.a == -1.001287) 测试了你的最后一次编辑,期望值被划分到a == -1.001287 所在的行,但我得到了一个空数据框。
    • 是的,这是因为这只是显示,不是真实值,获取真实值如下:df.iloc[1,0]。或者更好的是自己设置值,然后重试:df.iloc[1,0] = 1.2345; condition = df.a == 1.2345
    • 我没有关注,为什么condition = (df.a == -1.001287) 不起作用?
    • ix 现已弃用。
    【解决方案2】:

    如果您需要将两列更新为相同的值,我认为您可以使用loc

    df1.loc[df1['stream'] == 2, ['feat','another_feat']] = 'aaaa'
    print df1
       stream        feat another_feat
    a       1  some_value   some_value
    b       2        aaaa         aaaa
    c       2        aaaa         aaaa
    d       3  some_value   some_value
    

    如果您需要单独更新,一个选项是使用:

    df1.loc[df1['stream'] == 2, 'feat'] = 10
    print df1
       stream        feat another_feat
    a       1  some_value   some_value
    b       2          10   some_value
    c       2          10   some_value
    d       3  some_value   some_value
    

    另一个常见的选项是使用numpy.where:

    df1['feat'] = np.where(df1['stream'] == 2, 10,20)
    print df1
       stream  feat another_feat
    a       1    20   some_value
    b       2    10   some_value
    c       2    10   some_value
    d       3    20   some_value
    

    编辑:如果您需要在条件为True 的情况下划分所有不带stream 的列,请使用:

    print df1
       stream  feat  another_feat
    a       1     4             5
    b       2     4             5
    c       2     2             9
    d       3     1             7
    
    #filter columns all without stream
    cols = [col for col in df1.columns if col != 'stream']
    print cols
    ['feat', 'another_feat']
    
    df1.loc[df1['stream'] == 2, cols ] = df1 / 2
    print df1
       stream  feat  another_feat
    a       1   4.0           5.0
    b       2   2.0           2.5
    c       2   1.0           4.5
    d       3   1.0           7.0
    

    如果可以使用多个条件,请使用多个 numpy.wherenumpy.select:

    df0 = pd.DataFrame({'Col':[5,0,-6]})
    
    df0['New Col1'] = np.where((df0['Col'] > 0), 'Increasing', 
                              np.where((df0['Col'] < 0), 'Decreasing', 'No Change'))
    
    df0['New Col2'] = np.select([df0['Col'] > 0, df0['Col'] < 0],
                                ['Increasing',  'Decreasing'], 
                                default='No Change')
    
    print (df0)
       Col    New Col1    New Col2
    0    5  Increasing  Increasing
    1    0   No Change   No Change
    2   -6  Decreasing  Decreasing
    

    【讨论】:

    • 我更新了我的问题,我有超过 100 列,我该怎么做?
    • @Stanko - 我认为这是另一个问题 - 您需要以某种方式选择此 100 列。例如如果需要100 第一列,请使用df.columns[:100],然后将其传递给loc
    • 我不一定想要前 100 列,我只想将列的所有值(流列除外)除以 2,其中流为 f.e. 2
    • @Ambleu - 完全正确。
    • @MH - 好主意,添加到答案中。还有np.select 替代品。
    猜你喜欢
    • 1970-01-01
    • 2020-09-28
    • 2022-07-22
    • 2019-06-04
    • 2020-10-11
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 1970-01-01
    相关资源
    最近更新 更多