Проблема: Учитывая приведенный ниже раздел данных, я пытаюсь придумать код, который будет применять функцию к трем отдельным столбцам без необходимости писать три отдельных вызова функций.Применение подобных функций для нескольких столбцов в python/pandas
Код для данных:
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). Я хочу иметь возможность писать код, который будет обобщать и применять эту функцию к нескольким столбцам за один проход.
Я думал, что я мог бы создать списки столбцов и их соответствующие дни, используйте функцию «почтовый», и гнездо функции в цикле, но моя попытка ниже в конечном счете не:
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'")
Я не уверен, почему подход петли терпит неудачу. Независимо от того, я надеюсь получить рекомендации о том, как обобщать функцию приложения в пандах. Заранее спасибо!
Работали как очарование. Я решил, что моя проблема была концептуальной, поэтому благодарим за то, что мы изложили более согласованный план. Если у вас есть время, можете ли вы объяснить аргументы в лямбда-функции (строка, col = col, day = day)? –
@UncleMilton sure :) Лямбда может использовать только переменные, которые явно переданы ей, поэтому вы передаете ей 'col' и' day'. Это ленивая вещь, чтобы назвать параметры лямбда таким образом, вероятно, это было бы яснее: 'lambda var1, var2 = col, var3 = day: annualize_spend (var2, var3, var1)'. Таким образом, вы устанавливаете значения по умолчанию для * последних * двух параметров лямбда, тем самым эффективно предоставляя ему функцию с одним входом для 'apply'. Поскольку это только значения по умолчанию, лямбда также может работать в синтаксисе 2 или 3 входа, но 'apply' использует только одну переменную, поэтому она должна иметь не более 1 параметра, отличного от значения по умолчанию. –
: Ничего себе, спасибо за объяснение. Еще один (общий) вопрос: зачем передавать лямбду в функцию apply вместо самой функции? Вот почему df.apply (lambda row, col = col, day = day: annualize_spend (col, day, row) вместо просто df.apply (annualize_spend)? Какая эффективность/ценность достигается за счет использования лямбда-функциональности, когда функция уже был создан? (Я видел этот подход для гораздо более простых функций, и было любопытно, почему обращение к лямбда было необходимо, когда функция уже была создана). Еще раз спасибо, самое полезное! –