Python加速了大型嵌套数组处理

时间:2018-01-25 20:33:34

标签: python

我想知道是否有更快的方法来做到这一点。

"""
Structure
 -data[]
  -data[0] 
    -data[number, number, number, number, number, number, number]
    - ... ect X 12000
  -data[1]
    -data[number, number, number, number, number, number, number]
    - ... ect X 12000
  -data[2]
    -data[number, number, number, number, number, number, number]
    - ... ect X 12000
  -data[3] 
    -data[number, number, number, number, number, number, number]
    - ... ect X 12000
x and y are the first two numbers in each data array.
"""

我需要扫描第1,2,3层中每个项目对第一层(0)中的每个项目,以查看它们是否属于给定的搜索半径。这需要一段时间。

    for i in range (len(data[0])):

        x = data[0][i][0]
        y = data[0][i][1]

        for x in range (len(data[1])):
            x1 = data[1][x][0]
            y1 = data[1][x][1]

            if( math.pow((x1 -x),2) + math.pow((y1 - y),2) < somevalue):
                matches1.append(data[0][i])
                matches2.append(data[1][x])
                continue
            else:
                continue

感谢您的帮助!

4 个答案:

答案 0 :(得分:1)

首先,您应该编写更易读的python代码:

for x,y in data[0]:
    for x1, y1 in data[1]:
        if (x1 - x)**2 + (y1 - y)**2 < somevalue:
            matches1.append((x,y))
            matches2.append((x1,y1))

你可以用numpy向内化循环:

for x,y in data[0]:
    x1, y1 = data[1].T
    indices = (x1 - x)**2 + (y1 - y)**2 < somevalue
    matches.append(((x,y), data[1][indices]))

答案 1 :(得分:1)

对于这个特定问题scipy.spatial.KDTree或者更确切地说,它的Cython workalike scipy.spatial.cKDTree似乎是泰勒制造的:

import numpy as np
from scipy.spatial import cKDTree

# create some random data
data = np.random.random((4, 12000, 7))

# in each record discard all but x and y
data_xy = data[..., :2]

# build trees
trees = [cKDTree(d) for d in data_xy]

somevalue = 0.001

# find all close pairs between reference layer and other layers
pairs = []
for tree in trees[1:]:
    pairs.append(trees[0].query_ball_tree(tree, np.sqrt(somevalue)))

这个例子不到一秒钟。请注意,输出格式与脚本生成的格式不同。对于三个非参考层中的每一个,它是列表列表,其中索引k处的内部列表包含在参考列表中接近点k的点的索引。

答案 2 :(得分:0)

我建议使用装饰器@jit(nopython = True)创建一个函数并使用numba libray。

同样建议你应该使用numpy数组,因为numba专注于利用numpy操作。

from numba import jit

@jit(nopython=True)
def search(data):

  matches1 = []
  matches2 = []

  for i in range (len(data[0])):

    x = data[0][i][0]
    y = data[0][i][1]

    for x in range (len(data1[1])):
      x1 = data[1][x][0]
      y1 = data[1][x][1]

      if( math.pow((x1 -x),2) + math.pow((y1 - y),2) < somevalue):
          matches1.append(data[0][i])
          matches2.append(data[1][x])
          continue
      else:
          continue

  return matches1, matches2

if __name__ == '__main__':
  # Initialize
  # import your data however.
  m1, m2 = search(data)

关键是确保只使用numba支持的允许功能。

我已经看到速度从快100倍增加到快300倍。

答案 3 :(得分:0)

这也是使用GPGPU计算的好地方。从python你有pycuda和pyopencl取决于你的底层硬件。如果你没有gpu,Opencl也可以使用CPU上的一些SIMD指令 如果你不想沿着GPGPU路走,那么如前所述,numpy或numba也会很有用。