如何找到多个向量都是zeo的指数

时间:2017-11-10 19:22:45

标签: python numpy apache-spark pyspark sparse-matrix

初学者pySpark问题:

如何找到所有向量为零的索引?

经过一系列的变换后,我得到了一个带有~2.5M行的火花df和一个长度为~262K的tfidf稀疏向量。我想执行PCA降维以使这些数据对于多层感知器模型拟合更易于管理,但是pyspark的PCA最多限制为65,535列。

+--------------------+
|      tfidf_features| df.count() >>> 2.5M 
+--------------------+ Example Vector:
|(262144,[1,37,75,...| SparseVector(262144, {7858: 1.7047, 12326: 1.2993, 15207: 0.0953, 
|(262144,[0],[0.12...|      24112: 0.452, 40184: 1.7047,...255115: 1.2993, 255507: 1.2993})
|(262144,[0],[0.12...|
|(262144,[0],[0.12...|
|(262144,[0,6,22,3...|
+--------------------+

因此,我想删除所有~2.5M文档(行)为零的稀疏tfidf向量的指标或列。这有望让我低于PCA的最高65,535。

我的计划是创建一个udf(1)将稀疏向量转换为密集向量(或np数组)(2)搜索所有向量以查找所有向量为零的索引(3)删除索引。然而,我正在努力与第二部分(找到所有向量等于零的索引)。这是我到目前为止的地方,但我认为我的攻击计划过于耗时而且不是非常pythonic(特别是对于这么大的数据集):

import numpy as np    
row_count = df.count()
def find_zero_indicies(df):
     vectors = df.select('tfidf_features').take(row_count)[0]
     zero_indices = []
     to_delete = []
     for vec in vectors:
          vec = vec.toArray()
          for value in vec:
               if value.nonzero():
                    zero_indices.append(vec.index(value))
     for value in zero_indices:
          if zero_inices.count(value) == row_count:
               to_delete.append(value)
return to_delete

任何建议或帮助表示赞赏!

1 个答案:

答案 0 :(得分:2)

如果有的话,找到应该保留的索引更有意义:

from pyspark.ml.linalg import DenseVector, SparseVector
from pyspark.sql.functions import explode, udf
from operator import itemgetter

@udf("array<integer>")
def indices(v):
    if isinstance(v, DenseVector):
        return [i for i in range(len(v))]
    if isinstance(v, SparseVector):
        return v.indices.tolist()
    return []

indices_list = (df
    .select(explode(indices("tfidf_features")))
    .distinct()
    .rdd.map(itemgetter(0))
    .collect())

并使用VectorSlicer

from pyspark.ml.feature import VectorSlicer

slicer = VectorSlicer(
    inputCol="tfidf_features",
    outputCol="tfidf_features_subset", indices=indices_list)

slicer.transform(df)

然而,在实践中,我建议使用固定大小的矢量,使用HashingTF

HashingTF(inputCol="words", outputCol="tfidf_features", numFeatures=65535)

CountVectorizer

CountVectorizer(inputCol="words", outputCol="vectorizer_features", 
    vocabSize=65535)

在这两种情况下,您都可以将其与StopWordsRemover结合使用。