【问题标题】:Creating a very large sparse matrix csv from a list of condensed data从压缩数据列表中创建一个非常大的稀疏矩阵 csv
【发布时间】:2018-06-28 00:41:04
【问题描述】:

我有一本格式如下的字典:

{
  "sample1": set(["feature1", "feature2", "feature3"]),
  "sample2": set(["feature1", "feature4", "feature5"]),
}

我有 20M samples 和 150K 独特功能。

我想把这个转换成csv格式:

sample,feature1,feature2,feature3,feature4,feature5
sample1,1,1,1,0,0
sample2,1,0,0,1,1

到目前为止我做了什么:

  1. ALL_FEATURES = list(set(features))
  2. with open("features.csv", "w") as f:
        f.write("fvecmd5," + ",".join([str(x) for x in ALL_FEATURES]) + "\n")
        fvecs_lol = list(fvecs.items())
        fvecs_keys, fvecs_values = zip(*fvecs_lol)
        del fvecs_lol
        tmp = [["1" if feature in featurelist else "0" for feature in ALL_FEATURES] for featurelist in fvecs_values]
        for i, entry in enumerate(tmp):
            f.write(fvecs_keys[i] + "," + ",".join(entry) + "\n")
    

但这运行速度很慢。有更快的方法吗?也许利用 Numpy/Cython?

【问题讨论】:

  • 你可以从 tensorflow 或 sklearn 中检查一个热门函数

标签: python python-3.x pandas csv numpy


【解决方案1】:

你可以使用sklearn.feature_extraction.text.CountVectorizer,它会产生一个稀疏矩阵,然后创建一个SparseDataFrame:

In [49]: s = pd.SparseSeries(d).astype(str).str.replace(r"[{,'}]",'')

In [50]: s
Out[50]:
sample1    feature1 feature2 feature3
sample2    feature1 feature5 feature4
dtype: object

In [51]: from sklearn.feature_extraction.text import CountVectorizer

In [52]: cv = CountVectorizer()

In [53]: r = pd.SparseDataFrame(cv.fit_transform(s),
                                s.index, 
                                cv.get_feature_names(), 
                                default_fill_value=0)

In [54]: r
Out[54]:
         feature1  feature2  feature3  feature4  feature5
sample1         1         1         1         0         0
sample2         1         0         0         1         1

【讨论】:

  • 这在我的机器上运行了将近 11 个小时,然后内存不足:( 我赞成这个答案,因为它适用于较小的数据集。
【解决方案2】:

这是你需要的吗?

pd.Series(d).apply(','.join).str.get_dummies(sep=',')
Out[50]: 
         feature1  feature2  feature3  feature4  feature5
sample1         1         1         1         0         0
sample2         1         0         0         1         1

你可以在末尾添加to_csv

这个怎么样

s=pd.Series(d).to_frame('v')

s.v=list(map(','.join,s.v.values))

s.v.str.get_dummies(sep=',')
Out[86]: 
         feature1  feature2  feature3  feature4  feature5
sample1         1         1         1         0         0
sample2         1         0         0         1         1

【讨论】:

  • 这是一个非常棒的单线。我运行了这个并得到了一个内存错误:(我赞成这个答案,因为这正是我想要的,但这不是解决我的问题的东西
  • @LelouchLamperouge update another method 应该比apply快
  • 只是检查其他解决方案.. 请给我几分钟。他们还没有耗尽内存;)
  • 明确一点,问题不在于速度,而在于内存消耗(既然你说apply 应该更快)
  • @LelouchLamperouge 请告诉我,我的最后一个将是块
【解决方案3】:

因此,您希望将 CSV 从稀疏表示转换为密集表示。

怎么样? 您可以将 csv 加载到稀疏矩阵中(查看 scipy.coo_matrix 哪种适合您的情况),转换为密集的 numpy 数组(使用 np.array())并将其另存为 CSV(可能通过列表-列表优先)

(或者您可以按照其他人的建议使用一些花哨的 pandas 编码。)

然而,真正的问题是,为什么要以密集格式存储如此庞大的数据集?这在内存/磁盘空间方面效率极低,并且对于大型数据集,转换应该花费很长时间。 具体来说,如果您的数据集有 20M 样本和 150k 特征,那么密集表示将不适合您的内存,甚至可能不适合您的磁盘。

【讨论】:

  • 实际上恰恰相反。我有一个密集的表示并想创建一个稀疏的表示。我需要这样做,以便我可以从中制作散点图
  • 我想稀疏这个词是用来描述不同的事物的。字典格式是稀疏的,scipy.**sparse**.coo_matrix 是稀疏的,numpy 数组是密集的(这里,sparse 这个词是指数据结构的一个属性,而不是存储的值...)
  • 知道了。我需要将此作为输入 DataShader 的中间步骤,它希望 Point(x-coord, y-coord) 进行绘图。因此,一旦我拥有这种格式,我会将其推断为 xy
猜你喜欢
  • 2023-03-05
  • 2015-12-05
  • 1970-01-01
  • 1970-01-01
  • 2018-08-03
  • 1970-01-01
  • 2017-01-10
  • 2016-07-29
  • 1970-01-01
相关资源
最近更新 更多