代码之家  ›  专栏  ›  技术社区  ›  Bill Armstrong

熊猫数学运算,以列值为条件

  •  4
  • Bill Armstrong  · 技术社区  · 7 年前

    我需要做一个以第二列中的值为条件的数学运算。这里是设置。

    给出一个简单的数据帧( df )以下内容:

    df = pd.DataFrame({
        'col1' : ['A', 'A', 'B', np.nan, 'D', 'C'],
        'col2' : [2, 1, 9, 8, 7, 4],
        'col3': [0, 1, 9, 4, 2, 3],
        })
    
    In [11]: df
    Out[11]: 
      col1  col2  col3
    0    A     2     0
    1    A     1     1
    2    B     9     9
    3  NaN     8     4
    4    D     7     2
    5    C     4     3
    

    我可以添加新列( math )然后用一个基于10和的数学表达式填充它 col3 .

    df['math'] = 10 + df['col3']
    
    In [14]: df
    Out[14]: 
      col1  col2  col3  math
    0    A     2     0    10
    1    A     1     1    11
    2    B     9     9    19
    3  NaN     8     4    14
    4    D     7     2    12
    5    C     4     3    13
    

    但我无法理解的是,如何使表达式对另一列中的值有条件(例如,仅当 col1 == B )。预期输出为:

    In [14]: df
    Out[14]: 
      col1  col2  col3  math
    0    A     2     0   NaN
    1    A     1     1   NaN
    2    B     9     9    19
    3  NaN     8     4   NaN
    4    D     7     2   NaN
    5    C     4     3   NaN
    

    为了补充说明,我将使用一个变量 col1 A中的值 for loop .结果,我无法得到 .group_by() 按说明工作 here here .我想我在找这样的东西…

    df['math'] = 10 + df.loc[[df['col1'] == my_var], 'col3']
    

    这是我从上面第二个例子中的评论中得到的——但是我不能让它起作用。它抛出一个 ValueError 对于太多的值——也就是说,我试图同时传递过滤器和操作列,但它只期望过滤器。 This 所以post也使用 .loc 类似于我上面的表达-但是有一个静态的 第1列 .

    5 回复  |  直到 7 年前
        1
  •  4
  •   user3483203    7 年前

    使用 loc

    df['math'] = df.loc[df.col1.eq('B'), 'col3'].add(10)
    
      col1  col2  col3  math
    0    A     2     0   NaN
    1    A     1     1   NaN
    2    B     9     9  19.0
    3  NaN     8     4   NaN
    4    D     7     2   NaN
    5    C     4     3   NaN
    
        2
  •  5
  •   piRSquared    7 年前

    where

    我进行数学运算,然后用 pandas.Series.where 通过传递布尔序列 df.col1.eq('B')

    df.assign(math=df.col3.add(10).where(df.col1.eq('B')))
    
      col1  col2  col3  math
    0    A     2     0   NaN
    1    A     1     1   NaN
    2    B     9     9  19.0
    3  NaN     8     4   NaN
    4    D     7     2   NaN
    5    C     4     3   NaN
    
        3
  •  2
  •   BENY    7 年前

    使用:(不是一种安全的实现方法,请参阅下面的注释)

    df['New']=df.col3[df.col1=='B']+10
    df
    Out[11]: 
      col1  col2  col3   New
    0    A     2     0   NaN
    1    A     1     1   NaN
    2    B     9     9  19.0
    3  NaN     8     4   NaN
    4    D     7     2   NaN
    5    C     4     3   NaN
    

    更新

    pd.concat([df,(df.col3[df.col1=='B']+10).to_frame('New')],1)
    Out[51]: 
      col1  col2  col3   New
    0    A     2     0   NaN
    1    A     1     1   NaN
    2    B     9     9  19.0
    3  NaN     8     4   NaN
    4    D     7     2   NaN
    5    C     4     3   NaN
    
        4
  •  0
  •   Bill Armstrong    7 年前

    我也能做到以下几点…

    df['math'] = 10 + df.loc[df['col1'] == 'B']['col3']  
    

    这是上面@user3483203答案的变体。最终,我的 'B' 是一个变量,所以我修改了@rafaelc的注释。

        5
  •  0
  •   Bill Armstrong    7 年前

    它在投掷 ValueError 因为你没有正确使用LOC。下面是使用loc的解决方案:

    df.loc[:,'math'] = 10 + df.loc[df['col1'] == "B", 'col3']
    

    输出:

     col1 col2 col3 math
    0    A   2   0    NaN
    1    A   1   1    NaN
    2    B   9   9    19.0
    3    NaN 8   4    NaN
    4    D   7   2    NaN
    5    C   4   3    NaN