【问题标题】:How to apply a custom function to groups in a dask dataframe, using multiple columns as function input如何将自定义函数应用于 dask 数据框中的组,使用多列作为函数输入
【发布时间】:2020-03-17 11:17:12
【问题描述】:

我正在使用 dask 处理一个非常大的数据框。 数据框大致如下所示:

Col_1    Col_2   Bool_1   Bool_2
A        1       True     False
B        1       True     True
C        1       False    False
D        1       True     False
A        2       False    True
B        2       False    False
C        2       True     False
D        2       True     True

但它有数百万行。

我在代码的这一点上尝试做的是计算Bool_1Bool_2 之间在Col_2 中形成的每个组的Jaccard 距离。这是因为该程序的目的是为Col_2 中存在的每个组生成一行(每行有几个统计数据,我只报告相关的列)。

为此,我首先使用df.groupby("Col_2") 将数据帧按Col_2 分组,但后来我不知道如何继续。到目前为止,我尝试的每一次尝试都引发了错误。

1:我尝试定义一个函数 compute_jacc_dist() 并通过 apply(compute_jacc_dist, axis=1) 将其传递给组,但它与 args 和 kwargs 有问题(尤其是轴,请参阅 @987654321 @ ,我还不能解决)。

2:我尝试使用 from dask_distance import jaccard 并使用它来计算 Bool_1Bool_2 之间的 J 距离,但它会产生奇怪的结果(每个组返回 J=1 即使有是没有交叉点)。

3:我尝试compute() 数据框并使用以下方法遍历组:

for name, group in df.groupby("Col_2"):
   jacc = dask_distance.jaccard(group["Bool_1"], group["Bool_2"])

但是这个非常慢,因为它会触发计算,然后逐组对如此巨大的数据帧进行操作(即我不想使用它)。作为参考,具有此功能的脚本已运行两天,而我估计我尝试过的任何解决方案 #1 和 #2 如果设置正确,将在 1-2 小时内返回结果。

关于如何处理此问题的任何建议?我理想的解决方案是以适当的方式使用df.groupby("Col_1").apply(compute_jacc_dist)。非常感谢任何帮助!

【问题讨论】:

    标签: python pandas dataframe group-by dask


    【解决方案1】:

    经过几个小时的尝试,我是这样做的。如果您正在阅读此内容,您可能想阅读此 (How to apply euclidean distance function to a groupby object in pandas dataframe?) 和此 (Apply multiple functions to multiple groupby columns)。

    def my_function(x):
    
        d = {}
        v1 = np.array(x["Bool_1"])
        v2 = np.array(x["Bool_2"])
        intersection = np.logical_and(v1, v2).sum()
        union = np.logical_or(v1, v2).sum()
        d["Jaccard"] = float(intersection) / float(union)
        return pd.Series(d, index=["Jaccard"])
    
    df = df.groupby("Col_2").apply(my_function, meta={"Jaccard":"float16"}).compute()
    

    说明

    我创建了一个函数来计算我的数据框两列之间的 Jaccard 距离。在函数中,我创建了一个字典 (d),其中包含我的计算结果。

    拥有字典的好处是我可以添加任意数量的计算,尽管这里只有一个。

    然后该函数返回一个包含字典的pd.Series

    该函数应用于基于Col_2 的数据帧组。 meta 数据类型是在 apply() 中指定的,整个事情最后都有 compute(),因为它是一个 dask 数据帧,必须触发计算才能得到结果。

    apply() 应该有与输出列一样多的meta

    【讨论】:

      猜你喜欢
      • 2018-08-27
      • 2020-10-28
      • 2018-03-03
      • 2017-01-28
      • 2021-09-20
      • 2023-03-06
      • 2021-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多