【问题标题】:modifying 2 columns based on a condition in a different column根据不同列中的条件修改 2 列
【发布时间】:2019-08-31 11:13:30
【问题描述】:

我有以下 df 5 列,其中 aa 是 (ww+zz) 的总和:

     xx    yy    ww   zz  aa
A    5     3     4    2   6  
B    2     0     4    1   5
C    3     0     4    2   6
D    3     2     3    3   6

我期待每当yy列的值为0时,然后将zz的值添加到ww中,ww将其设置为零,如果zz的值不为零,则保持原样。

期望的输出是:

     xx    yy    ww   zz  aa
A    5     3     4    2   6  
B    2     0     5    0   5
C    3     0     6    0   6  
D    3     2     3    3   6

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    这就是你所追求的吗?

    df[['ww', 'zz']] = (
        df.apply(lambda x: [x.zz+x.ww, 0] if x.yy==0 else [x.ww, x.zz], axis=1)
        .apply(pd.Series)
    )
    
        xx  yy  ww  zz  aa
    A   5   3   4   2   6
    B   2   0   5   0   5
    C   3   0   6   0   6
    D   3   2   3   3   6
    

    如果关注性能,请使用此版本:

    (
        df.assign(y=df.yy.eq(0))
        .assign(ww=lambda x: x.zz.mul(x.y).add(x.ww))
        .assign(zz=lambda x: x.zz.mul(~x.y))
        .drop('y', axis=1)
    )
    

    【讨论】:

    • 虽然这行得通,但apply(pd.Series) 是你不想做的事情,因为它非常慢。
    • 另外,第一种方法可以写成df[['ww', 'zz']] = df.apply(lambda x: [x.zz+x.ww, 0] if x.yy==0 else [x.ww, x.zz], axis=1,result_type='expand')。在此处查看 anky_91 的答案stackoverflow.com/questions/57646384/…
    • 感谢@Erfan,如果关注性能,只需添加一个更快的版本。
    • @MarkWang,谢谢,我从未使用过该参数。很高兴每天都能学到新东西:-)
    • 使用lambda 两次将不再有效。这里有向量化的答案,OP可能不知道。
    【解决方案2】:

    创建一个掩码,将具有yy 列 eq 的行标识为0,并使用where 应用条件。

    mask_0 = df['yy'].eq(0)
    
    df['ww'] = df['zz'].where(mask_0,0) + df['ww']
    
    df['zz'] = df['zz'].where(~mask_0,0)
    

    【讨论】:

      【解决方案3】:

      使用np.where 有条件地将zz 添加到wwmask 以将zz 中的值替换为0 如果yy == 0

      m = df['yy'].eq(0)
      
      df['ww'] = np.where(m, df['ww'].add(df['zz']), df['ww'])
      df['zz'] = df['zz'].mask(m, 0)
      

      输出

         xx  yy  ww  zz  aa
      0   5   3   4   2   6
      1   2   0   5   0   5
      2   3   0   6   0   6
      3   3   2   3   3   6
      

      计时测试

      df = pd.concat([df]*200000, ignore_index=True)
      

      二凡

      %%timeit
      
      m = df['yy'].eq(0)
      
      df['ww'] = np.where(m, df['ww'].add(df['zz']), df['ww'])
      df['zz'] = df['zz'].mask(m, 0)
      
      13.8 ms ± 112 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
      

      艾伦

      %%timeit
      
      (
          df.assign(y=df.yy.eq(0))
          .assign(ww=lambda x: x.zz.mul(x.y).add(x.ww))
          .assign(zz=lambda x: x.zz.mul(~x.y))
          .drop('y', axis=1)
      )
      
      
      31.3 ms ± 2.36 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
      

      【讨论】:

        【解决方案4】:

        试试这个:

        >>> df=pd.DataFrame(data={"xx": [5,2,3,3], "yy": [3,0,0,2], "ww": [4,4,4,3], "zz": [2,1,2,3], "aa": [6,5,6,6]}, index=["A", "B", "C", "D"])
        >>> df["ww"][df["yy"]==0]=df["ww"]+df["zz"]
        >>> df["zz"][df["yy"]==0]=0
        >>> df
           xx  yy  ww  zz  aa
        A   5   3   4   2   6
        B   2   0   5   0   5
        C   3   0   6   0   6
        D   3   2   3   3   6
        

        【讨论】:

          猜你喜欢
          • 2018-11-29
          • 1970-01-01
          • 1970-01-01
          • 2023-02-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-14
          • 2022-12-02
          相关资源
          最近更新 更多