【问题标题】:Use lambda with pandas to calculate a new column conditional on existing column使用 lambda 和 pandas 计算以现有列为条件的新列
【发布时间】:2020-08-22 08:59:23
【问题描述】:

我需要在 pandas DataFrame 中创建一个新列,该列计算为 DataFrame 中 2 个现有列的比率。但是,比率计算中的分母会根据在 DataFrame 的另一列中找到的字符串的值而改变。

示例。样本数据集:

import pandas as pd
df = pd.DataFrame(data={'hand'      : ['left','left','both','both'], 
                        'exp_force' : [25,28,82,84], 
                        'left_max'  : [38,38,38,38], 
                        'both_max'  : [90,90,90,90]})

我需要根据df['hand']的条件新建一个DataFrame列df['ratio']

如果df['hand']=='left' 那么df['ratio'] = df['exp_force'] / df['left_max']

如果df['hand']=='both' 那么df['ratio'] = df['exp_force'] / df['both_max']

【问题讨论】:

  • np.where(df.hand.eq('left'), df['exp_force'] / df['left_max'], df['exp_force'] / df['both_max'])

标签: python pandas dataframe lambda


【解决方案1】:

你可以使用np.where():

import pandas as pd
df = pd.DataFrame(data={'hand'      : ['left','left','both','both'], 
                        'exp_force' : [25,28,82,84], 
                        'left_max'  : [38,38,38,38], 
                        'both_max'  : [90,90,90,90]})
df['ratio'] = np.where((df['hand']=='left'), df['exp_force'] / df['left_max'], df['exp_force'] / df['both_max'])
df

Out[42]: 
   hand  exp_force  left_max  both_max     ratio
0  left         25        38        90  0.657895
1  left         28        38        90  0.736842
2  both         82        38        90  0.911111
3  both         84        38        90  0.933333

或者,在现实生活中,如果你有很多条件和结果,那么你可以使用np.select(),这样你就不必像我做了很多一样重复你的np.where()语句在我的旧代码中。在这些情况下最好使用np.select

import pandas as pd
df = pd.DataFrame(data={'hand'      : ['left','left','both','both'], 
                        'exp_force' : [25,28,82,84], 
                        'left_max'  : [38,38,38,38], 
                        'both_max'  : [90,90,90,90]})
c1 = (df['hand']=='left')
c2 = (df['hand']=='both')
r1 = df['exp_force'] / df['left_max']
r2 = df['exp_force'] / df['both_max']
conditions = [c1,c2]
results = [r1,r2]
df['ratio'] = np.select(conditions,results)
df
Out[430]: 
   hand  exp_force  left_max  both_max     ratio
0  left         25        38        90  0.657895
1  left         28        38        90  0.736842
2  both         82        38        90  0.911111
3  both         84        38        90  0.933333

【讨论】:

    【解决方案2】:

    枚举

    for i,e in enumerate(df['hand']):
     
      if e == 'left':
        df.at[i,'ratio'] = df.at[i,'exp_force'] / df.at[i,'left_max']
      if e == 'both':
        df.at[i,'ratio'] = df.at[i,'exp_force'] / df.at[i,'both_max']
    df
    

    输出:

        hand    exp_force   left_max    both_max    ratio
    0   left    25            38          90      0.657895
    1   left    28            38          90      0.736842
    2   both    82            38          90      0.911111
    3   both    84            38          90      0.933333
    

    【讨论】:

    • 这与使用 numpy 相比会很慢
    【解决方案3】:

    您可以使用数据框的apply() 方法:

    df['ratio'] = df.apply(
        lambda x: x['exp_force'] / x['left_max'] if x['hand']=='left' else x['exp_force'] / x['both_max'],
        axis=1
    )
    

    【讨论】:

    • 确保将代码复制并粘贴到您的答案中,而不是图像中。
    • 与 numpy 方法相比,这会很慢
    猜你喜欢
    • 2019-04-09
    • 2017-02-03
    • 2017-03-01
    • 2020-12-09
    • 1970-01-01
    • 2022-12-15
    • 1970-01-01
    • 1970-01-01
    • 2018-12-04
    相关资源
    最近更新 更多