python - 将 pandas 数据帧转换为 cudf 数据帧时,缓冲区大小必须能被元素大小整除
问题描述
我有一个数据框,其中有一列是用引号编码的逗号分隔值,即字符串对象。前任:
df['a']
'1,2,3,4,5'
'2,3,4,5,6'
我能够将字符串格式的值列表转换为 NumPy 数组,并且能够成功执行我的操作。
def func(x):
return something
for t_df in pd.read_csv("testset.csv",chunksize=2000):
t_df['predicted'] = t_df['prev'].parallel_apply(lambda x : arima(ast.literal_eval(x),1))
直到现在我没有任何问题。但是func运行预测模型非常耗时,数据帧大小为 200 万条记录。
因此,我尝试了 python 中的 cudf 包来利用 Pandas 上的 GPU 功能,例如数据帧。这里问题出现了
for t_df in pd.read_csv("testset.csv",chunksize=2): t_df['prev'] = t_df['prev'].apply(lambda x : np.array(ast.literal_eval(x))) t_df = cudf.DataFrame.from_pandas(t_df)
当我应用相同的操作时,它因错误而失败,该错误基本上无法将类似字符串的对象转换为 NumPy 数组。错误如下
> ---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-19-e7866d751352> in <module>
12 t_df['prev'] = t_df['prev'].apply(lambda x : np.array(ast.literal_eval(x)))
13 st = time.time()
---> 14 t_df = cudf.DataFrame.from_pandas(t_df)
15 t_df['predicted'] = 10
16 res.append(t_df)
/opt/conda/lib/python3.7/site-packages/cudf/core/dataframe.py in from_pandas(cls, dataframe, nan_as_null)
3109 # columns for a single key
3110 if len(vals.shape) == 1:
-> 3111 df[i] = Series(vals, nan_as_null=nan_as_null)
3112 else:
3113 vals = vals.T
/opt/conda/lib/python3.7/site-packages/cudf/core/series.py in __init__(self, data, index, name, nan_as_null, dtype)
128
129 if not isinstance(data, column.ColumnBase):
--> 130 data = column.as_column(data, nan_as_null=nan_as_null, dtype=dtype)
131
132 if index is not None and not isinstance(index, Index):
/opt/conda/lib/python3.7/site-packages/cudf/core/column/column.py in as_column(arbitrary, nan_as_null, dtype, length)
1353 elif arb_dtype.kind in ("O", "U"):
1354 data = as_column(
-> 1355 pa.Array.from_pandas(arbitrary), dtype=arbitrary.dtype
1356 )
1357 else:
/opt/conda/lib/python3.7/site-packages/cudf/core/column/column.py in as_column(arbitrary, nan_as_null, dtype, length)
1265 mask=pamask,
1266 size=pa_size,
-> 1267 offset=pa_offset,
1268 )
1269
/opt/conda/lib/python3.7/site-packages/cudf/core/column/numerical.py in __init__(self, data, dtype, mask, size, offset)
30 dtype = np.dtype(dtype)
31 if data.size % dtype.itemsize:
---> 32 raise ValueError("Buffer size must be divisible by element size")
33 if size is None:
34 size = data.size // dtype.itemsize
ValueError: Buffer size must be divisible by element size
可能的解决方案是什么?
解决方案
与您的另一个问题一样,我相信您正试图强迫 cudf 以您确实不应该的方式做某事。 虽然 RAPIDS 致力于 API 熟悉度,但似乎:
- 您目前没有使用 cudf 或 cuml 最佳实践。虽然您的意图是可行的,但您并没有使用最佳实践来实现您的目标,而我们确实有资源。
- 尽管 RAPIDS 可以读取 csv 中的内容,但您的预处理正试图将 np.array 推送到单个列中,而 cudf 无法读取该格式(给您错误)。您需要将输出更改为 RAPIDS 可以读取的内容,例如为该数组中的每个元素创建一个列(下面的代码)。这可能是您遇到的 pandas 和 RAPIDS 之间的功能差距,我们鼓励您提出功能请求。
如果您还没有,我建议您在 github 上的 cuml 和 cudf 中浏览我们的一些文档和笔记本示例。 我们有一个在 GPU 上运行的 arima 示例笔记本。这些是一个非常快速的阅读,将真正让你上路。 可以用 本地处理字符串,但我们的字符串还不能很好地工作。如果您的 GPU 内存太小而无法包含所有数据,请使用 dask-cudf。 cudf
.str
apply
这里最棘手的部分是读取 CSV 中包含逗号分隔的字符串元素的数据集。您希望每个元素沿行进入其自己的列 - 而不是数组。RAPIDSapplys
在字符串上还不能很好地工作,但您想要完成的与下面的示例代码非常相似。可悲的是,RAPIDS 在这一点上可能需要比 Pandas 更长的时间。但是,该代码适用于 cudf 和 pandas,其输出在整个 RAPIDS 生态系统中更有用。既然您已将向量放入列中,请查看使用 cuml 的 ARIMA(上面链接)的位置。
import cudf
df = cudf.read_csv('testset.csv')
vecnum_cols = ['a']
df_vecnum = cudf.DataFrame(index=df.index)
if len(vecnum_cols) >0:
for vec in vecnum_cols:
v = df[vec].str.split(",", expand = True).reset_index(drop=True)
v.columns = [ vec + '_' + str(i) for i in range(v.shape[1])]
#print(len(v.columns))
df_vecnum = df_vecnum.join(v)
print(df_vecnum.head())
希望这一切都有帮助。我不能保证它会带你去你想去的地方,但根据我上面所看到的,它应该会让你朝着正确的方向前进。
推荐阅读
- ios - iOS 应用无法在 App Center 上构建:找不到 SQLCipher-prefix.pch
- javascript - TypeError: this._extensions.close 不是 webpack 中的函数
- sql - 重复的备用列
- python - firebase auth 未连接到 appengine 项目以登录用户
- flutter - 颤振使用flutter_html库更改html图像大小
- c++ - 为什么我需要在 header 中提供构造函数实现?C++
- ios - 如何在 IOS 中以编程方式安装证书
- android - 错误发生在 Android 应用程序中的空对象引用上的“java.lang.String com.example.myapplication.FindUSer.getUrlimage()”
- javascript - JS中根据href属性对dom元素进行排序
- calendarkit - 无法使用 CalendarKit 获取导航项