PySpark 2.2.0: у объекта 'numpy.ndarray' нет атрибута 'индексы' - PullRequest
4 голосов
/ 08 марта 2019

Задача

Я вычисляю размер по индексам в пределах __SparseVector__, используя Python API для Spark (PySpark).

Сценарий

def score_clustering(dataframe):
assembler = VectorAssembler(inputCols = dataframe.drop("documento").columns, outputCol = "variables")
data_transformed = assembler.transform(dataframe)
data_transformed_rdd = data_transformed.select("documento", "variables").orderBy(data_transformed.documento.asc()).rdd
count_variables = data_transformed_rdd.map(lambda row : [row[0], row[1].indices.size]).toDF(["id", "frequency"])

Выпуск

Когда я выполняю действие __.count()__ на фрейме данных __count_variables__, появляется ошибка:

AttributeError: у объекта 'numpy.ndarray' нет атрибута 'индексы'

Основная часть для рассмотрения:

data_transformed_rdd.map (лямбда-строка: [строка [0], строка [1] .indices.size]). ToDF (["id", "частота"])

Я полагаю, что этот кусок связан с ошибкой, но я не могу понять, почему исключение говорит о __numpy.ndarray__, если я делаю вычисления путем сопоставления того __lambda expression__, чей аргумент a __SparseVector__ (создан с __assembler__).

Есть предложения? Может кто-нибудь знает, что я делаю не так?

1 Ответ

1 голос
/ 14 марта 2019

Здесь есть две проблемы.Первый из них находится в indices.size call, indices и size - это два разных атрибута SparseVector class , size - полный размер вектора, а indices - векторные индексы, значения которыхненулевой, но size не является атрибутом indices.Итак, если предположить, что все ваши векторы являются экземплярами класса SparseVector:

from pyspark.ml.linalg import Vectors

df = spark.createDataFrame([(0, Vectors.sparse(4, [0, 1], [11.0, 2.0])),
                            (1, Vectors.sparse(4, [], [])),
                            (3, Vectors.sparse(4, [0,1,2], [2.0, 2.0, 2.0]))],
                           ["documento", "variables"])

df.show()

+---------+--------------------+
|documento|           variables|
+---------+--------------------+
|        0|(4,[0,1],[11.0,2.0])|
|        1|           (4,[],[])|
|        3|(4,[0,1,2],[2.0,2...|
+---------+--------------------+

Решением является len функция:

df = df.rdd.map(lambda x: (x[0], x[1], len(x[1].indices)))\
               .toDF(["documento", "variables", "frecuencia"])
df.show()  
+---------+--------------------+----------+
|documento|           variables|frecuencia|
+---------+--------------------+----------+
|        0|(4,[0,1],[11.0,2.0])|         2|
|        1|           (4,[],[])|         0|
|        3|(4,[0,1,2],[2.0,2...|         3|
+---------+--------------------+----------+

И здесь возникает вторая проблема: VectorAssembler не всегдагенерировать SparseVectors, в зависимости от того, что является более эффективным, SparseVector или DenseVectors могут быть сгенерированы (основываясь на количестве нулей, которые имеет ваш исходный вектор).Например, предположим, что следующий фрейм данных:

df = spark.createDataFrame([(0, Vectors.sparse(4, [0, 1], [11.0, 2.0])),
                             (1, Vectors.dense([1., 1., 1., 1.])),
                              (3, Vectors.sparse(4, [0,1,2], [2.0, 2.0, 2.0]))], 
                           ["documento", "variables"])

df.show()      
+---------+--------------------+
|documento|           variables|
+---------+--------------------+
|        0|(4,[0,1],[11.0,2.0])|
|        1|   [1.0,1.0,1.0,1.0]|
|        3|(4,[0,1,2],[2.0,2...|
+---------+--------------------+

Документ 1 является DenseVector, и решение предыдущих версий не работает, потому что DenseVectors не имеет атрибута indices, поэтому вам нужно использовать более общее представлениевекторы для работы с DataFrame, который содержит как разреженные, так и плотные векторы, например numpy:

import numpy as np
df = df.rdd.map(lambda x: (x[0], 
                           x[1], 
                           np.nonzero(x[1])[0].size))\
                .toDF(["documento", "variables", "frecuencia"])
df.show() 
+---------+--------------------+----------+
|documento|           variables|frecuencia|
+---------+--------------------+----------+
|        0|(4,[0,1],[11.0,2.0])|         2|
|        1|   [1.0,1.0,1.0,1.0]|         4|
|        3|(4,[0,1,2],[2.0,2...|         3|
+---------+--------------------+----------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...