python - Dask dataframe apply 在传递局部变量作为参数时给出意外的结果

标签 python pandas scope apply dask

当在 for 循环内调用 dask DataFrameapply 方法(其中我使用迭代器变量作为 apply 的参数)时,我稍后执行计算时会得到意想不到的结果。此示例显示了行为:

import dask.dataframe as dd
import random
import numpy as np

df = pd.DataFrame({'col_1':random.sample(range(10000), 10000), 
                   'col_2': random.sample(range(10000), 10000) })
ddf = dd.from_pandas(df, npartitions=8)

def myfunc(x, channel):
    return channel

for ch in ['ch1','ch2']:
    ddf[f'df_apply_{ch}'] = ddf.apply(lambda row: myfunc(row,ch), axis=1, meta=(f'df_apply_{ch}', np.unicode_))

print(ddf.head(5))

myfunc 的按行应用程序中,我希望看到另外两列,每一行上一列带有“ch1”,一列带有“ch2”。但是,这是脚本的输出:

   col_1  col_2 df_apply_ch1 df_apply_ch2
0   5485   2234          ch2          ch2
1   6338   6802          ch2          ch2
2   9408   5760          ch2          ch2
3   8447   1451          ch2          ch2
4   1230   3838          ch2          ch2

显然,循环的最终迭代覆盖了 apply 的第一个参数。事实上,以后在循环和调用 head 之间对 ch 的任何更改都会以同样的方式影响结果,覆盖我期望在两列中看到的内容。

这不是人们所看到的用纯 Pandas 做同样的练习。我还找到了 dask 的解决方法:

def myapply(ddf, ch):
    ddf[f'myapply_{ch}'] = ddf.apply(lambda row: myfunc(row,ch), axis=1, meta=(f'myapply_{ch}', np.unicode_))

for ch in ['ch1','ch2']:
    myapply(ddf, ch)

print(ddf.head(10))

给出:

   col_1  col_2 myapply_ch1 myapply_ch2
0   7394   3528         ch1         ch2
1   2181   6681         ch1         ch2
2   7945   1063         ch1         ch2
3   5164   8091         ch1         ch2
4   3569   2889         ch1         ch2

所以我发现这与用作应用参数的变量的范围有关,但我不明白为什么这种情况发生在 dask 中(仅)。这是预期的/预期的行为吗?

任何见解将不胜感激! :)

最佳答案

这毕竟是重复的,请参阅question on stackoverlow包括另一个解决方法。该行为的更详细解释可以在相应的issue on the dask tracker中找到。 :

This isn't a bug, this is just how python works. Closures evaluate based on the defining scope, if you change the value of trig in that scope then the closure will evaluate differently. The issue here is that this code would run fine in pandas, since there is an evaluation in each loop, but in dask all the evaluations are delayed until later, and thus all use the same value for trig.

其中 trig 是该讨论中使用的循环中的变量。

所以这不是一个 bug,也是 Python 的一个特性,由 dask 触发,而不是 pandas。

关于python - Dask dataframe apply 在传递局部变量作为参数时给出意外的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57379734/

相关文章:

python - 将点移动到最近的未占用网格位置

python - 仅当类别的所有项目都为 True 时才返回行

Javascript - "this"为空

python - CSound与Python通信

python - 具有缺失值的 SMOTE

Python 字符串递归,字符串索引超出范围

python - 根据另一个日期列将日期列添加到数据框

javascript - 对象字面量方法的范围

actionscript-2 - 如何将变量传递到 Action Script 2 中的内联函数

python - 使用 WN-Affect 检测字符串的情绪/心情