交织两个numpy阵列

dzh*_*lil 64 python arrays numpy

假设给出以下数组:

a = array([1,3,5])
b = array([2,4,6])
Run Code Online (Sandbox Code Playgroud)

如何有效地交织它们,以便得到像这样的第三个数组

c = array([1,2,3,4,5,6])
Run Code Online (Sandbox Code Playgroud)

可以假设length(a)==length(b).

Pau*_*aul 107

我喜欢Josh的回答.我只想添加一个更平凡,通常,稍微冗长的解决方案.我不知道哪个更有效率.我希望他们会有类似的表现.

import numpy as np
a = np.array([1,3,5])
b = np.array([2,4,6])

c = np.empty((a.size + b.size,), dtype=a.dtype)
c[0::2] = a
c[1::2] = b
Run Code Online (Sandbox Code Playgroud)

  • +1我玩时间和你的代码令人惊讶地似乎比输入快2-5倍.我仍然发现这些类型的操作的效率是非直观的,因此如果特定操作是代码中的瓶颈,使用`timeit`来测试事情总是值得的.在numpy中通常有多种方法可以做,所以绝对是个人资料代码片段. (6认同)
  • 除非速度真的很重要,否则我会选择这个,因为它更容易理解,如果有人想再次查看它,这一点很重要。 (2认同)

Jos*_*del 35

这是一个单行:

c = numpy.vstack((a,b)).reshape((-1,),order='F')
Run Code Online (Sandbox Code Playgroud)

  • 哇,这是如此难以理解:)这是其中一个案例,如果你不在代码中写一个正确的评论,它可以驱使某人疯狂. (13认同)
  • 这只是两个常见的numpy命令串在一起.我不认为这是不可读的,虽然评论永远不会伤害. (7认同)
  • @Ilya:我会亲自调用函数`.interleave()`:) (5认同)

MSe*_*ert 33

我认为检查解决方案在性能方面的表现可能是值得的.这就是结果:

在此输入图像描述

这清楚地表明,最受欢迎和接受的答案(Pauls答案)也是最快的选择.

该代码取自其他答案和另一个问答:

# Setup
import numpy as np

def Paul(a, b):
    c = np.empty((a.size + b.size,), dtype=a.dtype)
    c[0::2] = a
    c[1::2] = b
    return c

def JoshAdel(a, b):
    return np.vstack((a,b)).reshape((-1,),order='F')

def xioxox(a, b):
    return np.ravel(np.column_stack((a,b)))

def Benjamin(a, b):
    return np.vstack((a,b)).ravel([-1])

def andersonvom(a, b):
    return np.hstack( zip(a,b) )

def bhanukiran(a, b):
    return np.dstack((a,b)).flatten()

def Tai(a, b):
    return np.insert(b, obj=range(a.shape[0]), values=a)

def Will(a, b):
    return np.ravel((a,b), order='F')

# Timing setup
timings = {Paul: [], JoshAdel: [], xioxox: [], Benjamin: [], andersonvom: [], bhanukiran: [], Tai: [], Will: []}
sizes = [2**i for i in range(1, 20, 2)]

# Timing
for size in sizes:
    func_input1 = np.random.random(size=size)
    func_input2 = np.random.random(size=size)
    for func in timings:
        res = %timeit -o func(func_input1, func_input2)
        timings[func].append(res)

%matplotlib notebook

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(1)
ax = plt.subplot(111)

for func in timings:
    ax.plot(sizes, 
            [time.best for time in timings[func]], 
            label=func.__name__)  # you could also use "func.__name__" here instead
ax.set_xscale('log')
ax.set_yscale('log')
ax.set_xlabel('size')
ax.set_ylabel('time [seconds]')
ax.grid(which='both')
ax.legend()
plt.tight_layout()
Run Code Online (Sandbox Code Playgroud)

如果您有可用的numba,您也可以使用它来创建一个函数:

import numba as nb

@nb.njit
def numba_interweave(arr1, arr2):
    res = np.empty(arr1.size + arr2.size, dtype=arr1.dtype)
    for idx, (item1, item2) in enumerate(zip(arr1, arr2)):
        res[idx*2] = item1
        res[idx*2+1] = item2
    return res
Run Code Online (Sandbox Code Playgroud)

它可能比其他替代品略快一些:

在此输入图像描述

  • @user3613932 保罗的答案是蓝线。关于解释:越低意味着越快。蓝色和黄绿色线(numba/Paul)最低,因此速度最快。粉色和紫色(Tai 和 andersonvom)最高,因此最慢。我同意线条颜色并不容易区分,但您应该能够使用给定的代码轻松地重现图形。 (3认同)
  • 还要注意,可接受的答案比使用itertools中的[`roundrobin()`](https://docs.python.org/3/library/itertools.html#itertools-recipes)的本地Python解决方案要快_way_。食谱。 (2认同)

xio*_*xox 19

这是一些比以前更简单的答案

import numpy as np
a = np.array([1,3,5])
b = np.array([2,4,6])
inter = np.ravel(np.column_stack((a,b)))
Run Code Online (Sandbox Code Playgroud)

之后inter包含:

array([1, 2, 3, 4, 5, 6])
Run Code Online (Sandbox Code Playgroud)

这个答案似乎也略快一些:

In [4]: %timeit np.ravel(np.column_stack((a,b)))
100000 loops, best of 3: 6.31 µs per loop

In [8]: %timeit np.ravel(np.dstack((a,b)))
100000 loops, best of 3: 7.14 µs per loop

In [11]: %timeit np.vstack((a,b)).ravel([-1])
100000 loops, best of 3: 7.08 µs per loop
Run Code Online (Sandbox Code Playgroud)


and*_*vom 6

这将交错/交错这两个数组,我相信它是可读的:

a = np.array([1,3,5])      #=> array([1, 3, 5])
b = np.array([2,4,6])      #=> array([2, 4, 6])
c = np.hstack( zip(a,b) )  #=> array([1, 2, 3, 4, 5, 6])
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这一篇,因为它最具可读性。尽管事实上这是最慢的解决方案。 (2认同)
  • 将“zip”包装在“list”中以避免折旧警告 (2认同)

Ben*_*min 5

也许这比@JoshAdel的解决方案更具可读性:

c = numpy.vstack((a,b)).ravel([-1])
Run Code Online (Sandbox Code Playgroud)

  • [文档](http://docs.scipy.org/doc/numpy/reference/generated/numpy.ravel.html) 中`ravel` 的`order` 参数是`C`、`F` 之一, `A` 或 `K`。我认为你真的想要 `.ravel('F')`,用于 FORTRAN 顺序(列第一) (2认同)

小智 5

改进@xioxox 的回答:

import numpy as np
a = np.array([1,3,5])
b = np.array([2,4,6])
inter = np.ravel((a,b), order='F')
Run Code Online (Sandbox Code Playgroud)


clw*_*ght 5

我需要这样做,但是使用沿任意轴的多维数组。这是一个实现此效果的快速通用函数。它具有与 相同的调用签名np.concatenate,只是所有输入数组必须具有完全相同的形状。

import numpy as np

def interleave(arrays, axis=0, out=None):
    shape = list(np.asanyarray(arrays[0]).shape)
    if axis < 0:
        axis += len(shape)
    assert 0 <= axis < len(shape), "'axis' is out of bounds"
    if out is not None:
        out = out.reshape(shape[:axis+1] + [len(arrays)] + shape[axis+1:])
    shape[axis] = -1
    return np.stack(arrays, axis=axis+1, out=out).reshape(shape)
Run Code Online (Sandbox Code Playgroud)