即使一切似乎都是矢量化的,下面的代码运行得太慢了.
from numpy import *
from scipy.sparse import *
n = 100000;
i = xrange(n); j = xrange(n);
data = ones(n);
A=csr_matrix((data,(i,j)));
x = A[i,j]
Run Code Online (Sandbox Code Playgroud)
问题似乎是索引操作是作为python函数实现的,并且调用A[i,j]结果导致以下分析输出
500033 function calls in 8.718 CPU seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
100000 7.933 0.000 8.156 0.000 csr.py:265(_get_single_element)
1 0.271 0.271 8.705 8.705 csr.py:177(__getitem__)
(...)
Run Code Online (Sandbox Code Playgroud)
也就是说,python函数_get_single_element被调用100000次,这实在是效率低下.为什么不在纯C中实现?有没有人知道解决这个限制的方法,并加快上述代码?我应该使用不同的稀疏矩阵类型吗?
我使用Numpy在Python中有以下代码:
p = np.diag(1.0 / np.array(x))
Run Code Online (Sandbox Code Playgroud)
如何转换它以获得p2具有相同值的稀疏矩阵p而不创建p第一个?
在scipy.sparse中似乎没有一个方法给出了稀疏矩阵的最小值.特别是,我寻求最小的列.
文档中没有方法,numpy最小值不适用.如果X是稀疏矩阵,X.min()也会抛出错误:*** AttributeError: 'module' object has no attribute 'min'.
当然这必须是人们使用的东西.这是怎么做到的?
我目前想要将一个大的稀疏矩阵(~1M x 200k)与其转置相乘.结果矩阵的值将是浮点数.
实现这种乘法的有效方法是什么?因为我在计算中看到了一个模式.
我想知道哪些库可以更快地实现计算.它可以是Python,R,C,C++或任何其他.
c++ python linear-algebra sparse-matrix matrix-multiplication
我正在尝试利用新的AVX2 GATHER指令来加速稀疏矩阵 - 向量乘法.矩阵采用CSR(或耶鲁)格式,行指针指向列索引数组,而列索引数组又保存列.这样一个mat-vec mul的C代码看起来像这样:
for (int row = 0; row < n_rows - 1; row++) {
double rowsum = 0;
for (int col = row_ptr[row]; col < row_ptr[row + 1]; col++) {
rowsum += values[col] * x[col_indices[col]];
}
result[row] = rowsum;
}
Run Code Online (Sandbox Code Playgroud)
现在我的目标是通过AVX2内在函数加速这一点.以下代码适用于最新的英特尔或GCC,基于https://blog.fox-toolkit.org/?p=174.我删除了剩余部分,因为我的行都在4个双打(列%4 == 0)上对齐(幸运的是我).如果有人感兴趣,我也有处理余数的代码,但关键是,代码实际上稍慢.我检查了反汇编,对于上面的版本,只生成FP指令,对于我的AVX2代码,所有AVX2操作都按预期显示.即使使用适合缓存的小矩阵,AVX2版本也不行.我在这里很困惑......
double* value_base = &values[0];
double* x_base = &x[0];
int* index_base = &col_indices[0];
for (int row = 0; row < n_rows - 1; row++) {
int col_length = row_ptr[row + 1] - row_ptr[row]; …Run Code Online (Sandbox Code Playgroud) 我有一个大的稀疏矩阵 - 使用scipy的sparse.csr_matrix.值是二进制的.对于每一行,我需要计算相同矩阵中每行的Jaccard距离.最有效的方法是什么?即使对于10.000 x 10.000矩阵,我的运行时间也需要几分钟才能完成.
当前解决方案
def jaccard(a, b):
intersection = float(len(set(a) & set(b)))
union = float(len(set(a) | set(b)))
return 1.0 - (intersection/union)
def regions(csr, p, epsilon):
neighbors = []
for index in range(len(csr.indptr)-1):
if jaccard(p, csr.indices[csr.indptr[index]:csr.indptr[index+1]]) <= epsilon:
neighbors.append(index)
return neighbors
csr = scipy.sparse.csr_matrix("file")
regions(csr, 0.51) #this is called for every row
Run Code Online (Sandbox Code Playgroud) 我在网上找到了一些示例,展示了如何在Python中找到常规矩阵的零空间,但我找不到稀疏矩阵(scipy.sparse.csr_matrix)的任何示例.
零空间是指x使得M·x = 0,其中' · '是矩阵乘法.有人知道怎么做这个吗?
此外,在我的情况下,我知道零空间将由单个向量组成.这些信息可以用来提高方法的效率吗?
Julia中的分段/非连续范围是否有任何类型的对象类?例如,我可以创建一个常规范围:
a = UnitRange(1:5)
Run Code Online (Sandbox Code Playgroud)
但是,如果我想将其与其他范围结合起来:
b = UnitRange([1:5, 8:10, 4:7])
Run Code Online (Sandbox Code Playgroud)
我目前无法找到对象或方法.在这种情况下,有一个PiecewiseIncreasingRanges模块(https://github.com/simonster/PiecewiseIncreasingRanges.jl)正是我想要的,除了它,顾名思义,要求范围单调递增.
对此的上下文是我正在寻找一种方法来为具有重复行的稀疏矩阵创建SparseMatrixCSC类型的压缩,内存有效版本.RLEVectors模块可以很好地节省稀疏矩阵类中非零值向量的空间.现在虽然我试图找到一些东西来为行值矢量节省空间,同时也定义了稀疏矩阵,因为一系列重复行将导致该向量中的值范围(例如,前10行,甚至是某些列中的某些列)稀疏矩阵的前十行是相同的,那么行值向量中将存在大量的1:10模式.
更一般地说,我想要一个范围,比如我尝试在上面创建的b对象,我可以做一个迭代循环,得到:
for (idx, item) in enumerate(hypothetical_object)
println("idx: $idx, item: $item")
end
idx: 1, item: 1
idx: 2, item: 2
...
idx: 5, item: 5
idx: 6, item: 8
idx: 7, item: 9
idx: 8, item: 10
idx: 9, item: 4
idx: 10, item: 5
...
Run Code Online (Sandbox Code Playgroud)
更新:我正在考虑的一件事,如果我在这里没有听到其他建议,可能会尝试实现,只是创建一个PiecewiseIncreasingRange对象数组,一个用于稀疏矩阵中的每一列.(然后我可能还会将非零值向量分解为一个单独的片段数组,对于我的稀疏矩阵的每一列也是如此).这至少可以相对简单地实现.我不清楚这在计算效率方面与我在这个问题中寻找的对象类型之间的比较.我怀疑内存要求大致相同.
我有一个非常大的网络的数据非常稀疏.我想知道无论两个节点是否连接,什么是最有效的内存存储和最容易访问的方式.
显然,对于N个节点,保持N*N矩阵在我存储的空间方面不是那么有效.所以我想到可能保留下面的邻接列表:
Array(Vector{Int64}, N_tmp)
Run Code Online (Sandbox Code Playgroud)
其中N_tmp <= N,因为许多节点可能没有任何连接.
你能帮我看看是否有更好的方法或者包装在内存和访问方面更好?
问题:将sklearn的CountVectorizer和TfidfTransformer导致的稀疏矩阵转换为Pandas DataFrame列的最佳方法是什么,每个bigram及其相应的频率和tf-idf得分都有一个单独的行?
管道:从SQL DB中提取文本数据,将文本拆分为双字节并计算每个文档的频率和每个文档的每个文件的tf-idf,将结果加载回SQL DB.
当前状态:
引入两列数据(number,text).text清洁后产生第三列cleanText:
number text cleanText
0 123 The farmer plants grain farmer plants grain
1 234 The farmer and his son go fishing farmer son go fishing
2 345 The fisher catches tuna fisher catches tuna
Run Code Online (Sandbox Code Playgroud)
这个DataFrame被输入到sklearn的特征提取中:
cv = CountVectorizer(token_pattern=r"(?u)\b\w+\b", stop_words=None, ngram_range=(2,2), analyzer='word')
dt_mat = cv.fit_transform(data.cleanText)
tfidf_transformer = TfidfTransformer()
tfidf_mat = tfidf_transformer.fit_transform(dt_mat)
Run Code Online (Sandbox Code Playgroud)
然后在将矩阵转换为数组后将矩阵反馈到原始DataFrame中:
data['frequency'] = list(dt_mat.toarray())
data['tfidf_score']=list(tfidf_mat.toarray())
Run Code Online (Sandbox Code Playgroud)
输出:
number text cleanText \
0 123 The …Run Code Online (Sandbox Code Playgroud) sparse-matrix ×10
python ×6
scipy ×5
numpy ×4
julia ×2
avx2 ×1
c ×1
c++ ×1
dataframe ×1
indexing ×1
intrinsics ×1
pandas ×1
scikit-learn ×1