如何将spark rdd转换为numpy数组?

时间:2019-01-15 00:05:55

标签: python numpy apache-spark pyspark

我已使用spark上下文读取textFile,测试文件是csv文件。在testRdd下面是与我的rdd类似的格式。

testRdd = [[1.0,2.0,3.0,4.0,5.0,6.0,7.0],
[0.0,0.1,0.3,0.4,0.5,0.6,0.7],[1.1,1.2,1.3,1.4,1.5,1.6,1.7]]

我想将上面的rdd转换为numpy数组,因此可以将numpy数组输入到我的机器学习模型中。

当我尝试以下

 feature_vector = numpy.array(testRDD).astype(numpy.float32)

它给了我下面的TypeError:

TypeError: float() argument must be a string or a number

我应该如何将spark rdd转换为一个numpy数组。

3 个答案:

答案 0 :(得分:1)

在调用collect之前,您必须将数据numpy.array到本地计算机:

import numpy as np

a = np.array(testRdd.collect())
print(a)
#array([[ 1. ,  2. ,  3. ,  4. ,  5. ,  6. ,  7. ],
#       [ 0. ,  0.1,  0.3,  0.4,  0.5,  0.6,  0.7],
#       [ 1.1,  1.2,  1.3,  1.4,  1.5,  1.6,  1.7]])

或者如果您希望将每一行作为一个单独的数组:

b = testRdd.map(np.array).collect()
print(b)
#[array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.]),
# array([ 0. ,  0.1,  0.3,  0.4,  0.5,  0.6,  0.7]),
# array([ 1.1,  1.2,  1.3,  1.4,  1.5,  1.6,  1.7])]

答案 1 :(得分:0)

我最好的镜头是:

import pandas
arr = rdd.toDF().toPandas().values

rdd需要先转换为数据框,然后将数据框转换为大熊猫,然后再将其转换为基础值(numpy数组)。

编辑-您说您不喜欢这样,您是否尝试过制作地图?像这样:

arr = np.array()
rdd.map(lambda x: np.append(arr, x))

您应该包括在问题中尝试过的所有内容。

答案 2 :(得分:0)

我遇到了同样的问题,collect() 效率不高。

对我来说,在执行器上编写多个 numpy 文件效果很好,使用 numpy 加载多个文件没有问题。生成的文件数等于分区数。

就我而言,我不得不将文件放入 hdfs,因为我无法访问执行程序节点:

from pyspark.sql.types import *
from pyspark.sql.functions import spark_partition_id

def write_numy(list):
  import numpy as np
  from pyspark.taskcontext import TaskContext
  import os
  
  ctx = TaskContext()
  id = ctx.partitionId()
  
  local_path = "/tmp/test"+str(id)+".npy"
  hdfs_dest_path = "/tmp/test/"
  np.save(local_path, np.array(list))   
  os.system("hadoop fs -put "+local_path+" "+hdfs_dest_path)

schema = StructType([ StructField("ID", IntegerType()), StructField("TS", ArrayType( IntegerType()) )])
data = spark.createDataFrame(spark.sparkContext.parallelize(range(1, 1999)).map(lambda x: (x, range(1, 100)) ),schema)

data.rdd.foreachPartition(write_numy)