2016-03-25 3 views
0

Я хочу передать словарь в качестве дополнительного аргумента функции. Функция должна применяться к каждой строке кадра данных. Поэтому я использую «apply». Ниже у меня есть небольшой пример моей попытки:Python Pandas Apply, Pass Dictionary как аргумент

import pandas as pd 
import numpy as np 

def fun(df_row, dict1): 
return df_row['A']*2*max(dict1['x']) 

df = pd.DataFrame(np.random.randn(6,2),columns=list('AB')) 
dict_test = {'x': [1,2,3,4], 'y': [5,6,7,8]} 
df['D'] = df.apply(fun, args = (dict_test), axis = 1) 

Я получаю следующее сообщение об ошибке: ('весело() занимает ровно 1 аргумент (3 дано)', u'occurred по индексу 0') I использовать ** dict1 для обозначения пар ключ-значение в функции «весело»

Как ни странно, если я прохожу два заданы параметры, все работает отлично

def fun(df_row, dict1, dict2): 
return df_row['A']*2*max(dict1['x']) 

df = pd.DataFrame(np.random.randn(6,2),columns=list('AB')) 
dict_test = {'x': [1,2,3,4], 'y': [5,6,7,8]} 
df['D'] = df.apply(fun, axis = 1, args = (dict_test, dict_test)) 
+0

Вы не должны использовать '**'. Словарь будет передан как обычный аргумент, а не как аргументы ключевого слова. – zondo

+0

Если я удаляю **, я получаю ошибку ('fun() принимает ровно 2 аргумента (3 заданных)', u'occurred при индексе 0 ') – skr

+0

Если вы определяете 'fun()', чтобы принимать '* args' и печатать 'args', он должен дать вам представление о том, какие данные передаются ему. Вам определенно нужно добавить еще один параметр в свою функцию, но это должно сказать вам, что это такое. – zondo

ответ

1

Проблема в том, что вы не передаете кортеж, (dict_test) не является кортежем, это то же самое, что и dict_test. Вам нужен кортеж с dict_test как единственный элемент, то есть (dict_test,).

df['D'] = df.apply(fun, args=(dict_test,), axis=1) 
+0

Что такое запятая в 'args = (dict_test,)'? – conchoecia

+1

@conchoecia Это для [создания кортежа] (https://docs.python.org/3/library/stdtypes.html#tuple). – Goyo

1

с pd.DataFrame.apply документ:

Parameters 
---------- 
... 
args : tuple 
    Positional arguments to pass to function in addition to the 
    array/series 
Additional keyword arguments will be passed as keywords to the function 

Последняя строка означает, что если вы хотите распаковать dict_test передать аргументы в качестве ключевых слов к fun, вы можете сделать:

df['D'] = df.apply(fun, axis=1, **dict_test) 

Ранее вы использовали:

df['D'] = df.apply(fun, args = (dict_test), axis = 1) 

Это значит, что apply попытается позвонить в fun таким образом:

fun(df_row, dict_test) 

Но это не, как вы определили fun (вы получите разницу, когда вы знаете немного больше о позиционных и именованных аргументов).

+0

По-прежнему не работает: '(" fun() получил неожиданный аргумент ключевого слова 'y' ", u'occurred при индексе 0 ') ' – skr

+0

Это немного странно. Вы передаете '** dict_test' ** после ** всех остальных аргументов? – ldirer

+0

Да, точно так же, как вы набрали его – skr