python - DASK:当一方的 key 为 NA 时,合并会抛出错误,而 pd.merge 有效

标签 python pandas dask dask-dataframe pandas-merge

我有这些示例数据框:

tdf1 = pd.DataFrame([{"id": 1, "val": 4}, {"id": 2, "val": 5}, {"id": 3, "val": 6}, {"id": pd.NA, "val": 7}, {"id": 4, "val": 8}])
tdf2 = pd.DataFrame([{"some_id": 1, "name": "Josh"}, {"some_id": 3, "name": "Jake"}])

pd.merge(tdf1, tdf2, how="left", left_on="id", right_on="some_id").head()

并且合并工作完美。现在,如果我想使用 Dask 进行同样的操作:

dd_tdf1 = dd.from_pandas(tdf1, npartitions=10)
dd_tdf2 = dd.from_pandas(tdf2, npartitions=10)

dd_tdf2.merge(dd_tdf1, left_on="some_id", right_on="id", how="right", npartitions=10).compute(scheduler="threads").head()

我收到以下错误:

File /opt/conda/lib/python3.10/site-packages/pandas/core/reshape/merge.py:1585, in <genexpr>(.0)
   1581         return _get_no_sort_one_missing_indexer(left_n, False)
   1583 # get left & right join labels and num. of levels at each location
   1584 mapped = (
-> 1585     _factorize_keys(left_keys[n], right_keys[n], sort=sort, how=how)
   1586     for n in range(len(left_keys))
   1587 )
   1588 zipped = zip(*mapped)
   1589 llab, rlab, shape = (list(x) for x in zipped)

File /opt/conda/lib/python3.10/site-packages/pandas/core/reshape/merge.py:2313, in _factorize_keys(lk, rk, sort, how)
   2309 if is_integer_dtype(lk.dtype) and is_integer_dtype(rk.dtype):
   2310     # GH#23917 TODO: needs tests for case where lk is integer-dtype
   2311     #  and rk is datetime-dtype
   2312     klass = libhashtable.Int64Factorizer
-> 2313     lk = ensure_int64(np.asarray(lk))
   2314     rk = ensure_int64(np.asarray(rk))
   2316 elif needs_i8_conversion(lk.dtype) and is_dtype_equal(lk.dtype, rk.dtype):
   2317     # GH#23917 TODO: Needs tests for non-matching dtypes

File pandas/_libs/algos_common_helper.pxi:86, in pandas._libs.algos.ensure_int64()

TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NAType'

有没有人知道为什么会发生这种情况?

最佳答案

这扩展了@Michael Delgado 的评论。棘手的是 int64 不支持 pd.NA。你可以看到这个错误是由 pandas 通过尝试引发的:

tdf1['id'] = tdf1['id'].astype('int64')
# TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NAType'

一个修复是确保 iddtype 设置为 Int64(支持 pd.NA):

tdf1['id'] = tdf1['id'].astype('Int64')
tdf2['some_id'] = tdf2['some_id'].astype('Int64')

一旦数据类型相同,您就可以运行 dask 片段并获得所需的合并。

关于python - DASK:当一方的 key 为 NA 时,合并会抛出错误,而 pd.merge 有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74237866/

相关文章:

python - 根据数据框中的部分索引名称对列值求和

Python:引用变量(hack)

python - 使用 cherrypy 流式传输文件

python - 与列标题对应的引用 DataFrame 值

python - 将函数应用于 Pandas 数据框 : is there a more efficient way of doing this?

python - 当需要计算数据帧列时使用 dask 进行并行计算

python - Pandas 海峡计数

python - 如何将自定义函数应用于 dask 数据框中的组,使用多列作为函数输入

python - 使用 Dask 在大型集合上映射可变执行时间的函数

python - 如何洗牌 Dask 包中的元素