Python:如何使用Numpy向我的split函数进行向量化

时间:2015-05-23 12:41:32

标签: python numpy vectorization

我在Stack找到了解决问题的功能,但现在我想加快我的代码,因为我有很多要拆分的列表。

我听说向量化一个函数可以成为一个解决方案,所以试图用numpy对我的函数进行向量化,但它不起作用。

你能帮助我吗?

原始功能:

seq = ([1,1,5,1,5,5,1,5,1,1])

def zigzag(seq):
  return seq[::2], seq[1::2]

结果:

([1, 5, 5, 1, 1], [1, 1, 5, 5, 1])

我的矢量化尝试:

import numpy as np
seq = ([1, 1, 5, 1, 5, 5, 1, 5, 1, 1], [2, 2, 2, 3, 3, 3, 3, 2, 2, 2], [6, 3, 9, 2, 9, 4, 6, 3])

def zigzag(seq):
  return seq[::2], seq[1::2]

vecto = np.vectorize(zigzag)

vecto(seq)

期望的结果:

(([1, 5, 5, 1, 1], [1, 1, 5, 5, 1]), ([2, 2, 3, 3, 2], [2, 3, 3, 2, 2]), ([6, 9, 9, 6], [3, 2, 4, 3]))

1 个答案:

答案 0 :(得分:1)

单个数组很容易:只需将序列设为numpy.arrayzigzag函数就会调用C代码。

def zigzag(seq):
  return seq[::2], seq[1::2]

seq = np.array([1,1,5,1,5,5,1,5,1,1])

result = zigzag(seq)
print(result)

结果:

(array([1, 5, 5, 1, 1]), array([1, 1, 5, 5, 1]))

对于多维案例,您遇到的问题是列表的长度不同。因此,你无法做出很好的numpy.array。我建议你这样适应:

import numpy as np

def zigzag(seq):
    try:
        if len(seq.shape) == 1:
            return seq[::2], seq[1::2]
    except AttributeError:
        return [zigzag(x) for x in seq]

def main():
    options = _parse_args()

    seq = np.array([1,1,5,1,5,5,1,5,1,1])
    seq2 = (
        np.array([1, 1, 5, 1, 5, 5, 1, 5, 1, 1]),
        np.array([2, 2, 2, 3, 3, 3, 3, 2, 2, 2]),
        np.array([6, 3, 9, 2, 9, 4, 6, 3]),
    )

    print(zigzag(seq))
    print()
    print(zigzag(seq2))

第二个序列只是tuple的{​​{1}}。该函数检查您的序列是否具有numpy.array属性,这是一个良好的指示,它是shape。如果是这样,它使用NumPy切片。如果它是一个元组,它只会为每个元素调用numpy.array函数。

它为您的示例生成所需的输出:

zigzag

然而,这不是一个完美的解决方案。您不希望始终将Python列表和元组转换为NumPy数组。正如@hpaulj在评论中指出的那样,这种转换比分割Python (array([1, 5, 5, 1, 1]), array([1, 1, 5, 5, 1])) [(array([1, 5, 5, 1, 1]), array([1, 1, 5, 5, 1])), (array([2, 2, 3, 3, 2]), array([2, 3, 3, 2, 2])), (array([6, 9, 9, 6]), array([3, 2, 4, 3]))] list本身要长。考虑一下您拥有数据的位置以及将它们放在NumPy阵列中的意义。那些必须具有矩形形状。完成此操作后,您可以编写适当的tuple版本。