Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于二元矩阵元素包含的快速数组操作_Python_Arrays_Performance_Numpy - Fatal编程技术网

Python 基于二元矩阵元素包含的快速数组操作

Python 基于二元矩阵元素包含的快速数组操作,python,arrays,performance,numpy,Python,Arrays,Performance,Numpy,对于二维晶格中大量随机分布的点,我想有效地提取一个子阵列,它只包含元素,这些元素近似为索引,在单独的二维二进制矩阵中分配给非零值。目前,我的脚本如下所示: lat_len = 100 # lattice length input = np.random.random(size=(1000,2)) * lat_len binary_matrix = np.random.choice(2, lat_len * lat_len).reshape(lat_len, -1) def landed(inp

对于二维晶格中大量随机分布的点,我想有效地提取一个子阵列,它只包含元素,这些元素近似为索引,在单独的二维二进制矩阵中分配给非零值。目前,我的脚本如下所示:

lat_len = 100 # lattice length
input = np.random.random(size=(1000,2)) * lat_len
binary_matrix = np.random.choice(2, lat_len * lat_len).reshape(lat_len, -1)

def landed(input):
    output = []
    input_as_indices = np.floor(input)
    for i in range(len(input)):
        if binary_matrix[input_as_indices[i,0], input_as_indices[i,1]] == 1:
            output.append(input[i])
    output = np.asarray(output)
    return output   

然而,我怀疑一定有更好的方法来做到这一点。上面的脚本可能需要相当长的时间才能运行10000次迭代

你说得对。使用


这将使速度提高约150倍。

如果使用线性索引阵列,似乎可以显著提高性能。这里有一个矢量化的实现来解决我们的问题,类似于,但使用线性索引-

# Get floor-ed indices
idx = np.floor(input).astype(np.int)

# Calculate linear indices 
lin_idx = idx[:,0]*lat_len + idx[:,1]

# Index raveled/flattened version of binary_matrix with lin_idx
# to extract and form the desired output
out = input[binary_matrix.ravel()[lin_idx] ==1]
因此,简言之,我们有:

out = input[binary_matrix.ravel()[idx[:,0]*lat_len + idx[:,1]] ==1]
运行时测试-

本节将此解决方案中建议的方法与使用行-列索引的方法进行比较

案例1(原始数据量):

案例2(较大的数据量):


因此,这种线性索引的性能提升似乎约为
20%
-
30%

难以置信。你能解释一下什么变化在性能上产生了最大的差异,例如int的使用?性能上的差异是因为我们在python中避免了for循环,而是使用了高级numpy索引(我在上面添加了一个链接),而C中的编码效率更高。转换为整数只是一个副作用,由于索引不能有浮点
dtype
,必须是整数或布尔值。当您不忙于回答
numpy
问题时,请访问MATLAB聊天室:)我们想念您@瑞伦是马特拉班人的好地方!哎呀!我不是说“禁止”,而是说更像MATLAB人!我想当那里有更多的人时我会回来的:)马特拉比安:)好的,我最终会在那里见到你的!
out = input[binary_matrix.ravel()[idx[:,0]*lat_len + idx[:,1]] ==1]
In [62]: lat_len = 100 # lattice length
    ...: input = np.random.random(size=(1000,2)) * lat_len
    ...: binary_matrix = np.random.choice(2, lat_len * lat_len).
                                             reshape(lat_len, -1)
    ...: 

In [63]: idx = np.floor(input).astype(np.int)

In [64]: %timeit input[binary_matrix[idx[:,0], idx[:,1]] == 1]
10000 loops, best of 3: 121 µs per loop

In [65]: %timeit input[binary_matrix.ravel()[idx[:,0]*lat_len + idx[:,1]] ==1]
10000 loops, best of 3: 103 µs per loop
In [75]: lat_len = 1000 # lattice length
    ...: input = np.random.random(size=(100000,2)) * lat_len
    ...: binary_matrix = np.random.choice(2, lat_len * lat_len).
                                             reshape(lat_len, -1)
    ...: 

In [76]: idx = np.floor(input).astype(np.int)

In [77]: %timeit input[binary_matrix[idx[:,0], idx[:,1]] == 1]
100 loops, best of 3: 18.5 ms per loop

In [78]: %timeit input[binary_matrix.ravel()[idx[:,0]*lat_len + idx[:,1]] ==1]
100 loops, best of 3: 13.1 ms per loop