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

Posted

技术标签:

【中文标题】pandas.DataFrame:如何使用外部参数 applymap()【英文标题】:pandas.DataFrame: how to applymap() with external arguments 【发布时间】:2017-07-04 18:46:13 【问题描述】:

请参阅最后的更新以获得更清晰的描述。

根据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

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

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

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

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

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

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

我意识到如果我为df 使用 MultiIndexing 会更容易,但现在,这就是我正在使用的。有没有办法在熊猫中做我想做的事?理想情况下,我希望避免循环遍历 df 中的所有列,我不明白为什么 applymap 不接受关键字参数,而 apply 接受。

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


更新:

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

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,))

完全符合我的期望,并希望它做到。但是,尝试使用 DataFrame:

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,))

给我ValueError: Shape of passed values is (4, 10), indices imply (4, 4)

【问题讨论】:

【参考方案1】:

Pandas applymap 不接受参数,DataFrame.applymap(func)。如果您想将i 保持为状态,可以将其存储为由func 访问/修改的全局变量,或使用decorator

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

【讨论】:

查看更新。有没有办法让应用功能做我想要的?我不太明白它给我的错误(有很多文本),但我认为它试图返回bi-th 行,而不是每个元素的i-元素b. 您想在列表或系列上,还是在 2D 数据帧上使用 f? Pandas apply 沿 DataFrame 的输入轴应用函数。并且applymap 将函数应用于旨在按元素进行操作的 DataFrame,即像为 DataFrame 中的每个系列执行 map(func, series) 一样。 基本上我想要applymap的功能(所以在df/b的每个元素上应用func),同时能够将我的“外部”参数i传递给@ 987654340@。正如你所说,我似乎可以使用全局变量或函数属性或其他东西,或者只是将df 拆分为系列,但我只是想知道是否有办法直接在 pandas 中做到这一点。 这取决于您如何定义二维数组的i-th 元素?如果是i = row * n_col + col,pandas 没有直接的方法,但你可以考虑使用apply 两次或flattening the dataframe to a list first。【参考方案2】:

你可以使用它:

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))

【讨论】:

【参考方案3】:

这是一个将参数存储在嵌套方法中的解决方案

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))

【讨论】:

以上是关于pandas.DataFrame:如何使用外部参数 applymap()的主要内容,如果未能解决你的问题,请参考以下文章

合并 Pandas Dataframe:如何添加列和替换值

如何在 pandas.DataFrame 中插入满足条件的行值

Pandas.DataFrame.rename 方法中的参数“index”是啥?

pandas DataFrame apply()函数

Pandas DataFrame 作为函数的参数 - Python

004.pandas.DataFrame