通过 GPU 内核并行化 Pandas df.iterrows()

Paralleize Pandas df.iterrows() by GPU kernel

我编写了一个 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'

Note: This is a part of my program. I want to parallelize only this part using GPU.

提前致谢。

这种方法的动机是摆脱 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']]})

然后分解得到 tempprop 子列表元素的所有可能组合。在每个结果组中,我用 any 聚合并将其用作掩码键,用 's'.

替换相应的 prop 索引
>>> 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 子列表中的(相对任意的)元素数量是稳健的。也就是说,如果您的数据很大,您应该首先进行子集化以尽量减少内存使用。 Select 然后只执行适用的列。

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