首页 > 解决方案 > 通过 GPU 内核并行化 Pandas df.iterrows()

问题描述

我编写了一个 python 程序,在该程序中我需要检查给定值是否在给定数据集的列中。为此,我需要遍历每一行并检查每一行中列的相等性。这需要很多时间,因此我想在 GPU 中运行它。我在 CUDA C/C++ 方面有经验,但在 PyCuda 中没有并行化它的经验。谁能帮我解决这个问题?

for index, row in df.iterrows():
    s1 = set(df.iloc[index]['prop'])
    if temp in s1:
        df.iat[index, df.columns.get_loc('prop')] = 's'

注意:这是我的程序的一部分。我只想使用 GPU 并行化这部分。

提前致谢。

标签: pythonpandasparallel-processinggnu-parallel

解决方案


这种方法的动机是一种摆脱df.iterrows范式的手段,因为它的速度相对较低。虽然可以拆分为dask数据帧并执行某种并行apply功能,但我认为由于 Numpy/Pandas 向量化操作性能优势(如下图所示),向量化方法的速度可以接受。

在此处输入图像描述


我解释这段代码的方式基本上是“在prop列中,如果变量temp在该列的列表中,则将该列设置prop's'”。

for index, row in df.iterrows():
    s1 = set(df.iloc[index]['prop'])
    if temp in s1:
        df.iat[index, df.columns.get_loc('prop')] = 's'

我构建了一个测试数据框:

df = pd.DataFrame({'temp': ['re'] * 7, 
                   'prop': [['re', 'a'], ['ad', 'ed'], ['see', 'contra'], ['loc', 'idx'], 
                            ['reader', 'pandas'], ['alpha', 'omega'], ['a', 'z']]})

然后分解以获取temp针对prop子列表元素的所有可能组合。在每个结果组中,我聚合any并使用它作为掩码键,将相应的prop索引替换为's'.

>>> df['result'] = df['prop'].explode().eq(df['temp']).groupby(level=0).any()
>>> df['prop'] = df['prop'].mask(df['result'], 's')
>>> # df['prop'] = np.where(df['result'], 's', df['prop'])  # identical operation

  temp              prop  result
0   re                 s    True
1   re          [ad, ed]   False
2   re     [see, contra]   False
3   re        [loc, idx]   False
4   re  [reader, pandas]   False
5   re    [alpha, omega]   False
6   re            [a, z]   False

这个答案对于列中的逐行更改temp以及子列表中的(相对任意)数量的元素是稳健的prop。也就是说,如果您的数据很大,您应该首先进行子集化以最小化内存使用量。仅选择适用的列然后执行。

另请注意,这是df['prop'].explode().eq(df['temp'])有效的,因为该temp列是在已展开列的索引上广播的prop


推荐阅读