다음 배열이 주어진다고 가정하십시오.
a = array([1,3,5])
b = array([2,4,6])
이렇게 세 번째 배열을 얻을 수 있도록 효율적으로 짜맞추는 방법
c = array([1,2,3,4,5,6])
가정 할 수 있습니다 length(a)==length(b)
.
답변:
나는 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
timeit
특정 작업이 코드의 병목 현상 인 경우 항상 테스트 하는 데 사용할 가치가 있습니다. 일반적으로 numpy에서 작업을 수행하는 방법은 여러 가지가 있으므로 코드 조각을 확실히 프로파일 링하십시오.
.reshape
어레이의 추가 복사본을 생성하면 2 배의 성능 저하를 설명 할 수있을 것 같습니다. 그러나 항상 사본을 만드는 것은 아닙니다. 5x 차이가 작은 배열에만 있다고 생각합니까?
.flags
테스트 .base
하면 'F'형식으로 재구성하면 vstacked 데이터의 숨겨진 복사본이 생성되는 것처럼 보이므로 생각했던 것처럼 단순한보기가 아닙니다. 그리고 이상하게도 5x는 어떤 이유로 든 중간 크기의 배열에만 사용됩니다.
n
아이템으로 n-1
아이템을 엮을 수 있습니다.
성능 측면에서 솔루션의 성능을 확인하는 것이 가치가 있다고 생각했습니다. 그리고 이것이 그 결과입니다.
이것은 가장 많이 찬성되고 수락 된 답변 (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
다른 대안보다 약간 더 빠를 수 있습니다.
roundrobin()
itertools 조리법에서.
다음은 한 줄짜리입니다.
c = numpy.vstack((a,b)).reshape((-1,),order='F')
numpy.vstack((a,b)).interweave()
:)
.interleave()
개인적으로 :)
reshape
합니까?
다음은 이전 답변보다 간단한 답변입니다.
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
이것은 두 배열을 인터리브 / 인터레이스 할 것이며 꽤 읽기 쉽다고 생각합니다.
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])
zip
A의는 list
감가 상각 경고를 피하기 위해
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])
그리고 더 중요한 것은 이것은 임의의 모양 a
과b
또한 시도해 볼 수 있습니다. dstack
>>> a = array([1,3,5])
>>> b = array([2,4,6])
>>> dstack((a,b)).flatten()
>>> array([1, 2, 3, 4, 5, 6])
지금 옵션이 있습니다!
하나도 시도 할 수 있습니다 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)
을 참조하시기 바랍니다 documentation
및 tutorial
더 많은 정보를 얻을 수 있습니다.
나는 이것을해야했지만 모든 축을 따라 다차원 배열을 사용했습니다. 여기에 그 효과에 대한 빠른 범용 기능이 있습니다. 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)