在python/pandas中跨多列应用类似函数

2024-10-02 20:31:33 发布

您现在位置:Python中文网/ 问答频道 /正文

问题:给定下面的dataframe,我正在尝试编写代码,将一个函数应用于三个不同的列,而不必编写三个单独的函数调用。你知道吗

数据的代码:

import pandas as pd
data = {'name': ['Jason', 'Molly', 'Tina', 'Jake', 'Amy'],
    'days': [365, 365, 213, 318, 71],
    'spend_30day': [22, 241.5, 0, 27321.05, 345],
    'spend_90day': [22, 451.55, 64.32, 27321.05, 566.54],
    'spend_365day': [854.56, 451.55, 211.65, 27321.05, 566.54]}

df = pd.DataFrame(data)
cols = df.columns.tolist()
cols = ['name', 'days', 'spend_30day', 'spend_90day', 'spend_365day']
df = df[cols]
df

下面的函数基本上是将支出按年计算;如果某人在“天”列中的天数少于365天,则下面的函数将告诉我如果他们有365天,支出将是多少:

def annualize_spend_365(row):
    if row['days']/(float(365)) < 1:
        return (row['spend_365day']/(row['days']/float(365)))
    else:
        return row['spend_365day']

然后我将函数应用于特定列:

df.spend_365day = df.apply(annualize_spend_365, axis=1).round(2)
df

这正是我想要它的一列。但是,我不想为三个不同的“花费”列(30、90、365)中的每一个重写这个。我希望能够编写代码,将这个函数推广和应用到多个列在一次通过。你知道吗

我以为我可以创建列及其各自的日期列表,使用“zip”函数,并将函数嵌套在for循环中,但我下面的尝试最终失败了:

spend_cols = [df.spend_30day, df.spend_90day, df.spend_365day]
days_list = [30, 90, 365]

for col, day in zip(spend_cols, days_list):
    def annualize_spend(row):
        if (row.days/(float(day)) < 1:
            return (row.col)/((row.days)/float(day))
        else:
            return row.col
    col = df.apply(annualize_spend, axis = 1)

错误:

AttributeError: ("'Series' object has no attribute 'col'")

我不知道为什么循环方法会失败。不管怎样,我希望能为如何在熊猫中推广函数应用提供指导。提前谢谢!你知道吗


Tags: 函数代码namedfdatareturncolfloat
1条回答
网友
1楼 · 发布于 2024-10-02 20:31:33

请看两个函数定义:

def annualize_spend_365(row):
    if row['days']/(float(365)) < 1:
        return (row['spend_365day']/(row['days']/float(365)))
    else:
        return row['spend_365day']

以及

#col in [df.spend_30day, df.spend_90day, df.spend_365day]
def annualize_spend(row):
    if (row.days/(float(day)) < 1:
        return (row.col)/((row.days)/float(day))
    else:
        return row.col

看到区别了吗?一方面,在第一种情况下,您可以使用显式字段名访问字段,并且可以正常工作。在第二种情况下,您尝试访问row.col,但失败了,但在这种情况下col假定df中相应字段的值。不如试试

spend_cols = ['spend_30day', 'spend_90day', 'spend_365day']

在你的循环之前。另一方面,在语法df.days中,字段名实际上是“days”,但在df.col中,字段名不是字符串“col”,而是字符串col。因此,在后一种情况下也可能需要使用row[col]。不管怎样,我不确定在col上的循环中把col作为输出变量有多明智。你知道吗


我不熟悉pandas.DataFrame.apply,但可能使用单个函数定义,它将天数和感兴趣的字段作为输入变量:

def annualize_spend(col,day,row):
    if (row['days']/(float(day)) < 1:
        return (row[col])/((row['days'])/float(day))
    else:
        return row[col]

spend_cols = ['spend_30day', 'spend_90day', 'spend_365day']
days_list = [30, 90, 365]

for col, day in zip(spend_cols, days_list):
    col = df.apply(lambda row,col=col,day=day: annualize_spend(col,day,row), axis = 1)

当cd11.d>的一个参数空闲时,它将确保cd11.d>的一个参数空闲

相关问题 更多 >