为什么 Dask 在我的 Dataframe 中填写 "foo" 和 1

Why does Dask fill in "foo" and 1 in my Dataframe

我已经阅读了大约 15 个 csv 文件:

df = dd.read_csv("gs://project/*.csv", blocksize=25e6,
                 storage_options={'token': fs.session.credentials})

然后我持久化了 Dataframe(它使用 7.33 GB 内存):

df = df.persist()

我设置了一个新索引,因为我希望我在该字段上的分组依据尽可能高效:

df = df.set_index('column_a').persist()

现在我有181个分区,180个分区。 为了测试我的分组进行得有多快,我尝试了一个自定义应用函数,它只打印分组数据框:

grouped_by_index = df.groupby('column_a').apply(lambda n: print(n)).compute()

打印了一个包含正确列的 Dataframe,但值为“1”、"foo" 或 "True"。示例:

column_b  column_c column_d  column_e  column_f  column_g  \
index                                                                   
a          foo           1      foo        1           1           1

我也收到警告:

/opt/conda/lib/python3.7/site-packages/ipykernel_launcher.py:1: UserWarning: meta is not specified, inferred from partial data. Please provide meta if the result is unexpected. Before: .apply(func) After: .apply(func, meta={'x': 'f8', 'y': 'f8'}) for dataframe result or: .apply(func, meta=('x', 'f8'))
for series result """Entry point for launching an IPython kernel.

这是怎么回事?

确实,如果您阅读 apply 的文档,您会看到 meta= 是一个您可以传递的参数,它告诉 Dask 如何期望操作的输出看起来。这是必要的,因为 apply 可以做非常一般的事情。

如果您提供meta=,就像您的情况一样,Dask 将尝试使用包含 1 的示例迷你数据帧为操作播种任何数字列和 "foo" 用于文本列,只是为了查看输出结果。因为在你的 apply 中你打印了(实际上没有 return 任何东西),你看到了这个种子。

如文档所建议,您最好尽可能提供 meta=,这样就可以避免流程中的整个步骤。