alv*_*vas 10 python list matrix nested-lists scipy
我有这样的数据:
data = {'x':Counter({'a':1,'b':45}), 'y':Counter({'b':1, 'c':212})}
Run Code Online (Sandbox Code Playgroud)
我的标签是其中的键,data内部字典的键是功能:
all_features = ['a','b','c']
all_labels = ['x','y']
Run Code Online (Sandbox Code Playgroud)
我需要创建列表列表:
[[data[label][feat] for feat in all_features] for label in all_labels]
Run Code Online (Sandbox Code Playgroud)
[OUT]:
[[1, 45, 0], [0, 1, 212]]
Run Code Online (Sandbox Code Playgroud)
我len(all_features)的约为5,000,000,len(all_labels)约为100,000
最终目的是创建scipy稀疏矩阵,例如:
from collections import Counter
from scipy.sparse import csc_matrix
import numpy as np
all_features = ['a','b','c']
all_labels = ['x','y']
csc_matrix(np.array([[data[label][feat] for feat in all_features] for label in all_labels]))
Run Code Online (Sandbox Code Playgroud)
但循环遍历大量列表是相当低效的.
那么如何才能有效地查看大量列表呢?
是否有其他方法可以创建scipy矩阵,而data无需循环遍历所有功能和标签?
正如您所经历的那样,将词典字典转换为numpy或scipy数组并不是太有趣.如果你知道all_features并且all_labels事先知道,你可能最好从一开始就使用scipy稀疏COO矩阵来保持你的计数.
无论是否可行,您都希望按排序顺序保留功能和标签列表,以加快查找速度.所以我假设以下内容不会改变任何一个数组:
all_features = np.array(all_features)
all_labels = np.array(all_labels)
all_features.sort()
all_labels.sort()
Run Code Online (Sandbox Code Playgroud)
让我们data按照它们存储在字典中的顺序提取标签,并查看all_labels每个项目的位置:
labels = np.fromiter(data.iterkeys(), all_labels.dtype, len(data))
label_idx = np.searchsorted(all_labels, labels)
Run Code Online (Sandbox Code Playgroud)
现在让我们计算每个标签有多少个特征,并从中计算稀疏数组中非零项的数量:
label_features = np.fromiter((len(c) for c in data.iteritems()), np.intp,
len(data))
indptr = np.concatenate(([0], np.cumsum(label_features)))
nnz = indptr[-1]
Run Code Online (Sandbox Code Playgroud)
现在,我们提取每个标签的功能及其相应的计数
import itertools
features_it = itertools.chain(*(c.iterkeys() for c in data.itervalues()))
features = np.fromiter(features_it, all_features.dtype, nnz)
feature_idx = np.searchsorted(all_features, features)
counts_it = itertools.chain(*(c.itervalues() for c in data.itervalues()))
counts = np.fromiter(counts_it, np.intp, nnz)
Run Code Online (Sandbox Code Playgroud)
有了我们所拥有的,我们可以直接创建CSR矩阵,标签为行,功能为列:
sps_data = csr_matrix((counts, feature_idx, indptr),
shape=(len(all_labels), len(all_features)))
Run Code Online (Sandbox Code Playgroud)
唯一的问题是这个稀疏数组的行不是按顺序排列all_labels,而是按顺序迭代时出现的顺序排列data.但我们feature_idx告诉我们每个标签最终在哪里,我们可以通过以下方式重新排列行:
sps_data = sps_data[np.argsort(label_idx)]
Run Code Online (Sandbox Code Playgroud)
是的,它是混乱的,令人困惑的,可能不是很快,但它的工作原理,它会比你在你的问题中提出的内存效率更高:
>>> sps_data.A
array([[ 1, 45, 0],
[ 0, 1, 212]], dtype=int64)
>>> all_labels
array(['x', 'y'],
dtype='<S1')
>>> all_features
array(['a', 'b', 'c'],
dtype='<S1')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1379 次 |
| 最近记录: |