【问题标题】:Conditional replacement of pandas cell values with cell vlaues from another row用另一行中的单元格值有条件地替换 pandas 单元格值
【发布时间】:2016-04-23 05:00:32
【问题描述】:

我有一个 Pandas 数据框 pmov,其中 SDRFT 和 DRFT 列包含浮点值。某些 DRFT 值为 0.0。发生这种情况时,我想用 SDRFT 值替换 DRFT 值。出于测试目的,我将 DRFT = 0.0 的行存储在数据帧 df 中。

我已经尝试定义函数:

def SDRFT_is_DRFT(row):
    if row['SDRFT'] == row['DRFT']:
        pass
    elif row['SDRFT'] == 0:
        row['SDRFT'] = row['DRFT']
    elif ['DRFT'] == 0:
        row['DRFT'] = row['SDRFT']
    return row[['SDRFT','DRFT']]

并应用它:df.apply(SDRFT_is_DRFT, axis=1)

返回:

In []: df.apply(SDRFT_is_DRFT, axis=1)
Out[]: 
           SDRFT  DRFT
118    29.500000   0.0
144     0.000000   0.0
212    29.166667   0.0
250    21.000000   0.0
308    21.500000   0.0
317    24.500000   0.0
327    11.000000   0.0
334    31.000000   0.0
347    29.500000   0.0
348    35.000000   0.0

这不是我想要的结果。

我也试过这个功能:

def drft_repl(row):
    if row['DRFT']==0:
        row['DRFT'] = row['SDRFT']

这似乎适用于 df.DRFT = df.apply(drft_repl, axis=1)

pmov.DRFT = pmov.apply(drft_repl, axis=1) 导致 DRFT 值 100% 替换为 SDRFT 值,除非 DRFT 值为 nan。

如何有条件地将一列中的单元格值替换为同一行另一列中的值?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    试试这个:

    df.loc[df.DRFT == 0, 'DRFT'] = df.SDRFT 
    

    【讨论】:

      【解决方案2】:

      我认为你可以使用mask。首先将列SDRFT 替换为DRFT 的值,其中条件为True,最后将列DRFT 替换为SDRFT 的值:

      pmov.SDRFT = pmov.SDRFT.mask(pmov.SDRFT == 0, pmov.DRFT)
      pmov.DRFT = pmov.DRFT.mask(pmov.DRFT == 0, pmov.SDRFT)
      print pmov  
               SDRFT       DRFT
      118  29.500000  29.500000
      144   0.000000   0.000000
      212  29.166667  29.166667
      250  21.000000  21.000000
      308  21.500000  21.500000
      317  24.500000  24.500000
      327  11.000000  11.000000
      334  31.000000  31.000000
      347  29.500000  29.500000
      348  35.000000  35.000000
      

      loc 的另一个解决方案:

      pmov.loc[pmov.SDRFT == 0, 'SDRFT'] = pmov.DRFT 
      pmov.loc[pmov.DRFT == 0, 'DRFT'] = pmov.SDRFT 
      print pmov  
               SDRFT       DRFT
      118  29.500000  29.500000
      144   0.000000   0.000000
      212  29.166667  29.166667
      250  21.000000  21.000000
      308  21.500000  21.500000
      317  24.500000  24.500000
      327  11.000000  11.000000
      334  31.000000  31.000000
      347  29.500000  29.500000
      348  35.000000  35.000000
      

      为了更好的测试,DataFrame 已更改:

      print pmov
           SDRFT   DRFT
      118   29.5  29.50
      144    0.0   5.98
      212    0.0   7.30
      250   21.0   0.00
      308   21.5   0.00
      317    0.0   0.00
      327   11.0   0.00
      334   31.0   0.00
      347   29.5   0.00
      348   35.0  35.00
      
      pmov.SDRFT = pmov.SDRFT.mask(pmov.SDRFT == 0, pmov.DRFT)
      pmov.DRFT = pmov.DRFT.mask(pmov.DRFT == 0, pmov.SDRFT)
      print pmov 
           SDRFT   DRFT
      118  29.50  29.50
      144   5.98   5.98
      212   7.30   7.30
      250  21.00  21.00
      308  21.50  21.50
      317   0.00   0.00
      327  11.00  11.00
      334  31.00  31.00
      347  29.50  29.50
      348  35.00  35.00
      
      pmov.loc[pmov.DRFT == 0, 'DRFT'] = pmov.SDRFT 
      pmov.loc[pmov.SDRFT == 0, 'SDRFT'] = pmov.DRFT 
      print pmov  
           SDRFT   DRFT
      118  29.50  29.50
      144   5.98   5.98
      212   7.30   7.30
      250  21.00  21.00
      308  21.50  21.50
      317   0.00   0.00
      327  11.00  11.00
      334  31.00  31.00
      347  29.50  29.50
      348  35.00  35.00
      

      【讨论】:

      • 我首先尝试了 MaxU 的解决方案,该解决方案有效并回答了问题。这似乎也有效,并提供了一种替代方法。感谢两位!
      • 我认为他的回答不起作用,因为如果0 值在SDRFT 列中,则没有替换。尝试我的第二个 Dataframe 进行测试。他的解决方案只有在SDRFT 列中没有0 值时才有效。
      • 哦,我明白了。您的第二个解决方案是:pmov.loc[pmov.SDRFT == 0, 'SDRFT'] = pmov.DRFTpmov.loc[pmov.DRFT == 0, 'DRFT'] = pmov.SDRFT,这比 MaxU 的更彻底,正如您指出的那样,它只是以一种方式进行计算。我从 MaxU 的答案中进行了适当的替换,以在另一个方向进行计算,这导致了您的解决方案。再次感谢!
      猜你喜欢
      • 2019-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-21
      • 2019-05-16
      • 1970-01-01
      • 2014-04-17
      • 1970-01-01
      相关资源
      最近更新 更多