关于python:pandas.DataFrame:如何使用外部参数applymap()

pandas.DataFrame: how to applymap() with external arguments

有关更清楚的描述,请参见末尾的更新。

根据http://pandas.pydata.org/pandas-docs/version/0.18.1/generated/pandas.dataframe.apply.html,可以将外部参数传递给apply函数,但applymap:http://pandas.pydata.org/pandas-docs/version/0.18.1/generated/pandas.dataframe.applymap.html pandas.dataframe.applymap的情况并非如此。

我想应用一个elementwise函数f(a, i),其中a是元素,i是手工输入的参数。我需要这样做的原因是因为我将在一个循环中执行df.applymap(f)for i in some_list

举一个我想要的例子,假设我有一个数据框架df,其中每个元素都是numpy.ndarray。我想提取每个ndarrayi第个元素,并从中形成一个新的数据帧。所以我定义了我的f

1
2
def f(a, i):
    return a[i]

这样我就可以做一个循环,返回df中包含的每个np.ndarray的第i个元素:

1
2
for i in some_series:
    b[i] = df.applymap(f, i=i)

这样,在每次迭代中,它都会将我的i值传递到函数f中。

我意识到,如果我为df使用多索引的话,一切都会变得容易些,但现在,这正是我的工作。有没有办法在熊猫体内做我想做的事?理想情况下,我希望避免循环遍历df中的所有列,我不明白为什么applymap不接受关键字参数,而apply不接受关键字参数。

另外,我目前理解它的方式(我可能是错的),当我使用df.apply时,它会给我每行/每列的i第个元素,而不是df中包含的每一个ndarrayi第个元素。

更新:

所以我才意识到我可以把df分成系列,然后使用pd.Series.apply,它可以做我想做的。让我生成一些数据来说明我的意思:

1
2
3
4
5
6
7
8
def f(a,i):
    return a[i]

b = pd.Series(index=range(10), dtype=object)
for i in b.index:
    b[i] = np.random.rand(5)

b.apply(f,args=(1,))

做我所期望的,并希望它做。但是,尝试使用数据帧:

1
2
3
4
5
6
b = pd.DataFrame(index=range(4), columns=range(4), dtype=object)
for i in b.index:
    for col in b.columns:
        b.loc[i,col] = np.random.rand(10)

b.apply(f,args=(1,))

给了我一本书。


您可以使用它:

1
2
3
4
5
6
def matchValue(value, dictionary):
    return dictionary[value]

a = {'first':  1, 'second':  2}
b = {'first': 10, 'second': 20}
df['column'] = df['column'].map(lambda x: matchValue(x, a))

这是一种解决方案,其中参数存储在嵌套方法中

1
2
3
4
5
6
7
8
9
10
11
12
f(cell,argument):
   """Do something with cell value and argument"""
    return output

def outer(argument):
   def inner(cell):
        return f(cell,argument)

   return inner

argument = ...
df.applymap(func = outer(argument))


大熊猫applymap不接受争论,DataFrame.applymap(func)不接受争论。如果要将i保持为状态,可以将其存储为由func访问/修改的全局变量,也可以使用decorator

不过,我建议您尝试使用apply方法。