我对数组操作(点,外部,添加等)的最佳/最快方式感兴趣,同时忽略数组中的某些值.我最感兴趣的是一些(可能是50%-30%)的值被忽略的情况,并且对于中等大小的数组实际上是零,可能是100,000到1,000,000个元素.我能想到许多解决方案,但似乎没有一个能够从忽略某些值的可能优势中获益.例如:
import numpy as np
A = np.ones((dim, dim)) # the array to modify
B = np.random.random_integers(0, 1, (dim, dim)) # the values to ignore are 0
C = np.array(B, dtype = np.bool)
D = np.random.random((dim, dim)) # the array which will be used to modify A
# Option 1: zero some values using multiplication.
# some initial tests show this is the fastest
A += B * D
# Option 2: use indexing
# this seems to be the slowest
A[C] += D[C]
# Option 3: use masked arrays
A = np.ma.array(np.ones((dim, dim)), mask = np.array(B - 1, dtype = np.bool))
A += D
Run Code Online (Sandbox Code Playgroud)
EDIT1:
正如cyborg所建议的那样,稀疏数组可能是另一种选择.不幸的是我对包装不是很熟悉,也无法获得我能够获得的速度优势.例如,如果我有一个由稀疏矩阵定义的受限连接的加权图A
,另一个B
定义连通性的稀疏矩阵(1 =连通,0 =未连接)和密集的numpy矩阵C
,我希望能够做到类似的东西A = A + B.multiply(C)
,利用A
和B
稀疏.
使用稀疏矩阵,如果密度小于 10%,您可以获得改进。稀疏矩阵可能会更快,具体取决于您是否包含构建矩阵所需的时间。
import timeit
setup=\
'''
import numpy as np
dim=1000
A = np.ones((dim, dim)) # the array to modify
B = np.random.random_integers(0, 1, (dim, dim)) # the values to ignore are 0
C = np.array(B, dtype = np.bool)
D = np.random.random((dim, dim)) # the array which will be used to modify A
'''
print('mult '+str(timeit.timeit('A += B * D', setup, number=3)))
print('index '+str(timeit.timeit('A[C] += D[C]', setup, number=3)))
setup3 = setup+\
'''
A = np.ma.array(np.ones((dim, dim)), mask = np.array(B - 1, dtype = np.bool))
'''
print('ma ' + str(timeit.timeit('A += D', setup3, number=3)))
setup4 = setup+\
'''
from scipy import sparse
S = sparse.csr_matrix(C)
DS = S.multiply(D)
'''
print('sparse- '+str(timeit.timeit('A += DS', setup4, number=3)))
setup5 = setup+\
'''
from scipy import sparse
'''
print('sparse+ '+str(timeit.timeit('S = sparse.csr_matrix(C); DS = S.multiply(D); A += DS', setup4, number=3)))
setup6 = setup+\
'''
from scipy import sparse
class Sparsemat(sparse.coo_matrix):
def __iadd__(self, other):
self.data += other.data
return self
A = Sparsemat(sparse.rand(dim, dim, 0.5, 'coo')) # the array to modify
D = np.random.random((dim, dim)) # the array which will be used to modify A
anz = A.nonzero()
'''
stmt6=\
'''
DS = Sparsemat((D[anz[0],anz[1]], anz), shape=A.shape) # new graph based on random weights
A += DS
'''
print('sparse2 '+str(timeit.timeit(stmt6, setup6, number=3)))
Run Code Online (Sandbox Code Playgroud)
输出:
mult 0.0248420299535
index 0.32025789431
ma 0.1067024434
sparse- 0.00996273276303
sparse+ 0.228869672266
sparse2 0.105496183846
Run Code Online (Sandbox Code Playgroud)
编辑:您可以使用上面的代码(setup6
)来扩展scipy.sparse.coo_matrix
。它保持稀疏格式。
归档时间: |
|
查看次数: |
1317 次 |
最近记录: |