두 개의 numpy 배열 짜기


84

다음 배열이 주어진다고 가정하십시오.

a = array([1,3,5])
b = array([2,4,6])

이렇게 세 번째 배열을 얻을 수 있도록 효율적으로 짜맞추는 방법

c = array([1,2,3,4,5,6])

가정 할 수 있습니다 length(a)==length(b).


1
같은 질문은 어떻습니까?하지만 행렬을 인터리브하려고합니다. 즉, a와 b는 3 차원이며 첫 번째 차원에서 반드시 동일한 크기는 아닙니다. 참고 : 첫 번째 차원 만 인터리브되어야합니다.
Geronimo

답변:


144

나는 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

1
속도가 정말 중요하지 않은 한, 누군가가 그것을 다시 볼 때 중요한 것이 훨씬 더 이해하기 쉽기 때문에 이것을 사용하겠습니다.
John Salvatier 2011 년

6
+1 나는 타이밍을 가지고 놀았고 당신의 코드는 놀랍게도 입력에 따라 2-5 배 빠른 것 같습니다. 여전히 이러한 유형의 작업의 효율성이 직관적이지 않다는 것을 알기 때문에 timeit특정 작업이 코드의 병목 현상 인 경우 항상 테스트 하는 데 사용할 가치가 있습니다. 일반적으로 numpy에서 작업을 수행하는 방법은 여러 가지가 있으므로 코드 조각을 확실히 프로파일 링하십시오.
JoshAdel

@JoshAdel : .reshape어레이의 추가 복사본을 생성하면 2 배의 성능 저하를 설명 할 수있을 것 같습니다. 그러나 항상 사본을 만드는 것은 아닙니다. 5x 차이가 작은 배열에만 있다고 생각합니까?
Paul

내 솔루션을 보고 .flags테스트 .base하면 'F'형식으로 재구성하면 vstacked 데이터의 숨겨진 복사본이 생성되는 것처럼 보이므로 생각했던 것처럼 단순한보기가 아닙니다. 그리고 이상하게도 5x는 어떤 이유로 든 중간 크기의 배열에만 사용됩니다.
JoshAdel 2011 년

이 답변의 또 다른 장점은 길이가 같은 배열로 제한되지 않는다는 것입니다. n아이템으로 n-1아이템을 엮을 수 있습니다.
EliadL

62

성능 측면에서 솔루션의 성능을 확인하는 것이 가치가 있다고 생각했습니다. 그리고 이것이 그 결과입니다.

여기에 이미지 설명 입력

이것은 가장 많이 찬성되고 수락 된 답변 (Pauls 답변) 이 가장 빠른 옵션 임을 분명히 보여줍니다 .

코드는 다른 답변과 다른 Q & A 에서 가져 왔습니다 .

# 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()

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

다른 대안보다 약간 더 빠를 수 있습니다.

여기에 이미지 설명 입력


2
또한 참고로 허용 대답은 방법 빨리와 기본 파이썬 솔루션보다 roundrobin()itertools 조리법에서.
Brad Solomon

41

다음은 한 줄짜리입니다.

c = numpy.vstack((a,b)).reshape((-1,),order='F')

16
와우, 이건 너무 읽을 수 없어요 :) 이것은 코드에 적절한 주석을 쓰지 않으면 누군가를 미치게 만들 수있는 경우 중 하나입니다.
Ilya Kogan 2011 년

9
함께 묶인 두 가지 일반적인 numpy 명령입니다. 댓글이 아프지는 않지만 읽을 수 없다고 생각합니다.
JoshAdel

1
@JohnAdel, 음, 그렇지 않아 numpy.vstack((a,b)).interweave():)
일리아 년 Kogan

6
@Ilya : 나는 기능이라고했을 .interleave()개인적으로 :)
JoshAdel

무엇을 reshape합니까?
Danijel

23

다음은 이전 답변보다 간단한 답변입니다.

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

여기 inter에는 다음 이 포함됩니다.

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

이 답변은 또한 약간 더 빠른 것으로 보입니다.

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

10

이것은 두 배열을 인터리브 / 인터레이스 할 것이며 꽤 읽기 쉽다고 생각합니다.

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])

2
나는 이것이 가장 읽기 쉬운 것으로 좋아한다. 가장 느린 솔루션이라는 사실에도 불구하고.
kimstik

zipA의는 list감가 상각 경고를 피하기 위해
마일로 Wielondek

6

아마도 이것은 @JoshAdel의 솔루션보다 더 읽기 쉽습니다.

c = numpy.vstack((a,b)).ravel([-1])

2
ravelorder에서 인수 문서는 중 하나입니다 C, F, A, 또는 K. .ravel('F')FORTRAN 주문 (열 우선)에 대해 정말 원하는 것 같아요
Nick T

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')

1

vstack 확실히 옵션이지만 귀하의 경우에 대한 더 간단한 해결책은 hstack

>>> a = array([1,3,5])
>>> b = array([2,4,6])
>>> hstack((a,b)) #remember it is a tuple of arrays that this function swallows in.
>>> array([1, 3, 5, 2, 4, 6])
>>> sort(hstack((a,b)))
>>> array([1, 2, 3, 4, 5, 6])

그리고 더 중요한 것은 이것은 임의의 모양 ab

또한 시도해 볼 수 있습니다. dstack

>>> a = array([1,3,5])
>>> b = array([2,4,6])
>>> dstack((a,b)).flatten()
>>> array([1, 2, 3, 4, 5, 6])

지금 옵션이 있습니다!


7
질문은 정렬과 관련이 없으므로 첫 번째 답변에 -1. 두 번째 답변에 +1, 지금까지 본 것 중 최고입니다. 이것이 여러 솔루션을 여러 답변으로 게시해야하는 이유입니다. 여러 답변으로 나누어주세요.
endolith

1

또 다른 한 줄 : np.vstack((a,b)).T.ravel()
하나 더 :np.stack((a,b),1).ravel()


0

하나도 시도 할 수 있습니다 np.insert. ( Interleave numpy 배열 에서 마이그레이션 된 솔루션 )

import numpy as np
a = np.array([1,3,5])
b = np.array([2,4,6])
np.insert(b, obj=range(a.shape[0]), values=a)

을 참조하시기 바랍니다 documentationtutorial더 많은 정보를 얻을 수 있습니다.


0

나는 이것을해야했지만 모든 축을 따라 다차원 배열을 사용했습니다. 여기에 그 효과에 대한 빠른 범용 기능이 있습니다. 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.