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

2024-10-02 02:30:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个非常大的数据帧,我正在用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

但它有数百万行

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

为此,我首先使用df.groupby("Col_2")通过Col_2对数据帧进行分组,但是我不知道如何继续。到目前为止,我每次尝试都会出错

1:我试图定义一个函数compute_jacc_dist(),并通过apply(compute_jacc_dist, axis=1)将其传递给组,但它与args和kwargs有问题(特别是轴,请参见https://github.com/dask/dask/issues/1572,我还无法解决)

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)。非常感谢任何帮助


Tags: 数据函数falsetrue距离dfdistgroup
1条回答
网友
1楼 · 发布于 2024-10-02 02:30:18

经过几个小时的尝试,以下是我是如何做到的。如果你正在读这个,你可能想读这个(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应与输出列的数量相同

相关问题 更多 >

    热门问题