3

我有一个具有以下属性的 NumPy 数组:

  • 形状:(9986080, 2)
  • 数据类型:np.float32

我有一个方法可以遍历数组的范围,执行一个操作,然后将结果输入到新数组:

def foo(arr):
    new_arr = np.empty(arr.size, dtype=np.uint64)
    for i in range(arr.size):
        x, y = arr[i]
        e, n = ''
        if x < 0:
            e = '1'
        else:
            w = '2'
        if y > 0:
            n = '3'
        else:
            s = '4'
        new_arr[i] = int(f'{abs(x)}{e}{abs(y){n}'.replace('.', ''))
4

2 回答 2

1

我同意 Iguananaut 的评论,即这种数据结构似乎有点奇怪。我最大的问题是尝试向量化将字符串中的整数组合在一起然后将其重新转换为整数真的很棘手。不过,这肯定会有助于加快功能:

def foo(arr):
    x_values = arr[:,0]
    y_values = arr[:,1]
    ones = np.ones(arr.shape[0], dtype=np.uint64)
    e = np.char.array(np.where(x_values < 0, ones, ones * 2))
    n = np.char.array(np.where(y_values < 0, ones * 3, ones * 4))
    x_values = np.char.array(np.absolute(x_values))
    y_values = np.char.array(np.absolute(y_values))
    x_values = np.char.replace(x_values, '.', '')
    y_values = np.char.replace(y_values, '.', '')
    new_arr = np.char.add(np.char.add(x_values, e), np.char.add(y_values, n))
    return new_arr.astype(np.uint64)

在这里,输入数组的 x 和 y 值首先被拆分。然后我们使用向量化计算来确定 1 或 2、3 或 4 的位置en位置。最后一行使用标准列表推导来执行字符串合并位,这对于超大数组来说仍然很慢,但比常规的快环形。向量化先前的计算也应该大大加快函数的速度。

编辑: 我之前弄错了。Numpy 确实有一种使用 np.char.add() 方法处理字符串连接的好方法。这需要使用 . 将x_values和转换y_values为 Numpy 字符数组np.char.array()。同样由于某种原因,该np.char.add()方法只将两个数组作为输入,因此需要先连接x_valuesey_values然后n连接这些结果。尽管如此,这还是向量化了计算并且应该非常快。由于您进行了相当奇怪的操作,代码仍然有点笨拙,但我认为这将帮助您大大加快功能。

于 2020-08-26T16:29:40.833 回答
0

您可以使用np.apply_along_axis. 当您将此函数与另一个以行(或列)作为参数的函数一起提供时,它会执行您想要执行的操作。

对于你的情况,你可以重写函数如下:

def foo(row):
        x, y = row
        e, n = ''
        if x < 0:
            e = '1'
        else:
            w = '2'
        if y > 0:
            n = '3'
        else:
            s = '4'
        return int(f'{abs(x)}{e}{abs(y){n}'.replace('.', ''))


# Where you want to you use it.
new_arr = np.apply_along_axis(foo, 1, n)
于 2020-08-26T18:40:45.163 回答