【问题标题】:List operation with CUDF dataframe使用 CUDF 数据框进行列表操作
【发布时间】:2022-07-02 07:59:57
【问题描述】:

我有一个像这样的 Cudf 数据框

POSITION_ANTENNA1POSITION_ANTENNA2 的 dtype 是列表,我想构造一个列 = POSITION_ANTENNA1 - POSITION_ANTENNA2强>。但是,它给了我一个错误

Lists concatenation for this operation is not yetsupported

但是,如果我将数据框转换为 Pandas,它工作正常。有没有办法在不将其转换为 pandas 的情况下进行简单的列表操作。

编辑:

这是我正在尝试做的操作

df_merged['BASELINE'] = df_merged.POSITION_ANTENNA1-df_merged.POSITION_ANTENNA2

我收到此错误

但是,如果我执行以下操作,则可以正常工作

df_merged['BASELINE'] = df_merged.POSITION_ANTENNA1.to_pandas()-df_merged.POSITION_ANTENNA2.to_pandas()

【问题讨论】:

  • “如果我将数据帧转换为 Pandas,它工作正常” - 请显示在 pandas 中工作的代码、预期输出以及您如何尝试使用 dask 调用它。
  • 如果您想执行这样的算术运算,您应该在数据框中将标量作为值。数据框的目的不是为了高效或方便地将序列作为值。
  • 对我来说,这在熊猫中不起作用。 df = pd.DataFrame({'pt1': [[35.2, -110.0], [47.3, -68.2]], 'pt2': [[34.8, -109.8], [46.8, -70.1]]}); df.pt2 - df.pt1 引发了类似的错误。我强烈建议您遵循 Paul H 的建议——pandas 和 dask 旨在使用与 numpy 兼容的统一数据类型的列,如 float、int、string,而不是列表等对象类型。虽然您可以在数据框中保存对象,但像这样的数学运算不会按预期工作(请注意,+ 不会出错,但它只是连接列表)。如果这在 pandas 中对你有用,你能告诉我们minimal reproducible example吗?
  • 哦 - 刚刚看到您的评论,单元格是 ndarrays。我的意思是你可以按照 SultanOrazbayev 下面的建议去做。但是,如果您更改格式以使数据框性能更好并且更易于使用,这对您的同事来说将是一个好处。否则,您将始终不得不为每个操作拼凑出这样的变通方法。
  • 我希望我可以更改数据框,但这不取决于我。它是来自望远镜的标准数据帧,整个社区都遵循这种格式。

标签: python pandas dataframe dask rapids


【解决方案1】:

如果不访问示例数据,这个问题很难可靠地解决,但下面的代码 sn-p 应该是调整实际用例的良好起点。

作为一般建议,我建议首先使用 pandas 解决一个较小的案例(因为 dask 和 cudf 都提供了对 pandas 数据帧进行操作的能力):

from pandas import DataFrame, concat

df = DataFrame({"a": [[1, 2], [3, 4]], "b": [[5, 7], [9, 11]]})


def calculate_difference(df):
    # create dfs using https://stackoverflow.com/a/35491399/10693596

    _a = DataFrame(df["a"].tolist(), columns=["0", "1"], index=df.index)
    _b = DataFrame(df["b"].tolist(), columns=["0", "1"], index=df.index)
    _diff = _a - _b
    return concat([df, _diff], axis=1)


print(calculate_difference(df))
#         a        b  0  1
# 0  [1, 2]   [5, 7] -4 -5
# 1  [3, 4]  [9, 11] -6 -7

在函数中,我们依靠this answer,先将数据转换成索引一致的列,然后找出列值的差异。

假设上面生成了想要的结果,我们可以跨数据帧块映射函数(因为操作是按行完成的,不需要跨分区的数据交换):

from dask.dataframe import from_pandas

# will use the pandas example to provide meta (highly recommended)
meta = calculate_difference(df)

ddf = from_pandas(df, npartitions=1)
ddf = ddf.map_partitions(calculate_difference, meta=meta)

print(ddf.compute())
#         a        b  0  1
# 0  [1, 2]   [5, 7] -4 -5
# 1  [3, 4]  [9, 11] -6 -7

对于 dask cudf,您可以将 dask cudf 转换为 dask 数据帧:

from dask_cudf import from_cudf

# assuming df is a cudf dataframe
ddf = from_cudf(df, npartitions=2)

# will use the pandas example to provide meta (highly recommended)
meta = calculate_difference(df.head(3))
ddf = ddf.map_partitions(calculate_difference, meta=meta)

【讨论】:

  • 感谢您的回答,但问题是我不想将其转换为 Pandas,我想在 GPU 中进行所有操作。对于熊猫,操作要简单得多,就像我在原帖中提到的那样。但我正在寻找一种在 CUDF 或 DASK_CUDF 中进行整个操作的解决方案,因为将对大量数据进行批量并行处理,主要关注的是速度,因为这种操作已经使用 X-array 和 Dask 完成之前。
【解决方案2】:

SultanOrazbayev 是对的(+1ed):您无法通过在数据框中格式化数据的方式来做您想做的事。就个人而言,我会将 POSITION_ANTENNA1 和 POSITION_ANTENNA2 分解为两个单独的数据帧,对两个单独的数据帧进行减法运算,然后将结果放入您想要的 cudf 数据帧并删除两个天线数据帧以获得空间。

请在 cuDF 中提出功能请求,以便我们跟踪并优先考虑此使用。

【讨论】:

    猜你喜欢
    • 2018-05-04
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多