【问题标题】:Defining a function to be used on a DataFrame using .apply()使用 .apply() 定义要在 DataFrame 上使用的函数
【发布时间】:2018-12-29 00:11:11
【问题描述】:

我想定义带有包含一列或多列数据框的签名的自定义函数。

我尝试复制文章“如何将 Pandas '应用'函数应用于多个列?”中提到的解决方案,但我无法理解需要设置函数以接受来自其他列的数据作为输入的方式.

我的代码示例:

import pandas as pd

df=pd.DataFrame({'NAME':['A','B','C','D'],'HOURS':[38, 52, 1040, 28],'ROLE':['Manager','Expert','Expert','Expert']})

def apply_rate(col1='HOURS', col2='ROLE'):
    if row[col2]=='Manager': return row[col1]*165
    else: return row[col1]*135

df['TOTAL']=df.apply(lambda row: apply_rate(row['HOURS'],row['ROLE']),axis=1)

我收到一条消息“KeyError: ('Manager', 'occurred at index 0')”,但我卡在这个阶段,我不知道如何摆脱这个阻塞点。

【问题讨论】:

    标签: python python-3.x pandas dataframe apply


    【解决方案1】:

    诀窍是完全删除lambda。将您的 函数 提供给 pd.DataFrame.apply,并可能直接将您的附加函数参数提供给 apply

    def apply_rate(row, col1, col2):
        if row[col2]=='Manager': return row[col1]*165
        else: return row[col1]*135
    
    df['TOTAL'] = df.apply(apply_rate, axis=1, col1='HOURS', col2='ROLE')
    
    print(df)
    
      NAME  HOURS     ROLE   TOTAL
    0    A     38  Manager    6270
    1    B     52   Expert    7020
    2    C   1040   Expert  140400
    3    D     28   Expert    3780
    

    但是,逐行操作效率低下,推荐使用 Pandas。您可以通过按列操作轻松矢量化您的算法:

    df['TOTAL'] = df['HOURS'] * np.where(df['ROLE'] == 'Manager', 165, 135)
    

    另一种更易于扩展的版本可以使用字典映射:

    factor_map = {'Manager': 165}
    df['TOTAL'] = df['HOURS'] * df['ROLE'].map(factor_map).fillna(135)
    

    【讨论】:

    • 真的是一个很好的答案。很明显,它让我走出了小死胡同。它在问题之外很有用(我真的很喜欢'.fillna(135)' - 在这种情况下,从来没有想过像'else'一样使用它)。所以,即使它不完全符合礼仪......谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    • 2019-04-03
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多