如何使用 PySpark 将二维 RDD 中的字符串转换为 int

How do I convert strings in a 2-D RDD to int using PySpark

我是 pyspark 的新手,几个小时以来一直在努力解决这个问题。

目前,我的 RDD 如下所示:

[['74', '85', '123'], ['73', '84', '122'], ['72', '83', '121'], ['70', '81', '119'], ['70', '81', '119'], ['69', '80', '118'], ['70', '81', '119'], ['70', '81', '119'], ['76', '87', '125'], ['76', '87', '125']]

我希望它看起来像这样(所有条目都是整数):

[[74, 85, 123], [73, 84, 122], [72, 83, 121], [70, 81, 119], [70, 81, 119], [69, 80, 118], [70, 81, 119], [70, 81, 119], [76, 87, 125], [76, 87, 125]]

我得到的最接近的方法是使用 flatMap 转换为一维数组,然后将条目转换为整数。但是,我希望一次处理三个整数(一次计算条目 3 的总和和平均值),并且我认为将其保存在二维数组中是最简单的方法。我也尝试了列表理解,但它们似乎不起作用,因为它不是列表。 任何帮助将不胜感激!

更新

在执行以下操作之前,您可以使用 mapcollect 将您的 RDD 转换为列表。

rdd = spark.sparkContext.parallelize(data)
list_string = rdd.map(list).collect()

使用列表理解实际上足够快速有效,可以将所有字符串转换为整数。多练习就会知道对付的方法了。

list_value = [[int(i) for i in list_] for list_ in list_string]

print(list_value)
[[74, 85, 123], [73, 84, 122], [72, 83, 121], [70, 81, 119], [70, 81, 119], [69, 80, 118], [70, 81, 119], [70, 81, 119], [76, 87, 125], [76, 87, 125]]

二维数组中的求和和平均也是如此。

list_sum = [sum(vector) for vector in list_value]
list_sum = [sum(vector)/len(vector) for vector in list_value]

或者更好,只需使用 NumPy 即可。

array = np.array(list_value)

np.sum(array, axis = 1)
Out[174]: array([282, 279, 276, 270, 270, 267, 270, 270, 288, 288])

np.average(array, axis=1)
Out[175]: array([94., 93., 92., 90., 90., 89., 90., 90., 96., 96.])

为了比较速度,我创建了一个列表和一个 (1000,3) 的数组。希望这能让您清楚地了解它们的效率。

%timeit np.sum(array, axis=1)
%timeit [sum(vector) for vector in list_value]

20.3 µs ± 412 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
167 µs ± 3 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit np.average(array, axis=1)
%timeit [sum(vector)/len(vector) for vector in list_value]

29.3 µs ± 536 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
256 µs ± 23.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

但是,对于小型二维列表集,它比使用 NumPy 数组更快。