我在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]))
答案 0 :(得分:1)
单个数组很容易:只需将序列设为numpy.array
,zigzag
函数就会调用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
版本。