python - 通过 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 并行化这部分。
提前致谢。
解决方案
这种方法的动机是一种摆脱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
。
推荐阅读
- python - Python pandas:获取组的第一个值
- ruby-on-rails - 为什么 RailsAdmin 加载我的编辑视图这么慢?
- continuous-integration - 如何在 Gitlab 上运行的 CI 作业中仅重试失败的测试?
- amazon-web-services - AWS API Gateway - 为 CloudWatch Log 启用 $input
- swift - Swift ui macos @Published nil 或 Int
- python - 根据给定的索引对列表连接二维数组行的有效方法
- python - Pandas read_csv 不读取文件(while 循环)
- xamarin - 使用动态数据将 IObservable 转换为 SourceCache
- excel - 使用计时器增加单元格值
- java - 正则表达式选择不带括号的点之间的组