[python] Numpy 배열에 새 차원을 추가하려면 어떻게해야합니까?
나는 이미지의 numpy 배열로 시작합니다.
In[1]:img = cv2.imread('test.jpg')
모양은 640×480 RGB 이미지에 대해 예상 할 수있는 것입니다.
In[2]:img.shape
Out[2]: (480, 640, 3)
하지만 제가 가지고있는이 이미지는 100 프레임 길이의 비디오 프레임입니다. 이상적으로, 나는 그런 것을이 비디오에서 모든 데이터를 포함하는 단일 배열하고 싶은 img.shape
반환 (480, 640, 3, 100)
.
다음 프레임, 즉 다음 이미지 데이터 세트, 또 다른 480 x 640 x 3 어레이를 초기 어레이에 추가하는 가장 좋은 방법은 무엇입니까?
답변
NumPy 배열에 차원을 추가하는 방법을 묻습니다. 그러면 해당 차원이 새 데이터를 수용하도록 확장 될 수 있습니다. 차원은 다음과 같이 추가 할 수 있습니다.
image = image[..., np.newaxis]
답변
또는
image = image[..., np.newaxis]
에 @dbliss ‘대답 , 당신은 또한 사용할 수 있습니다 numpy.expand_dims
처럼
image = np.expand_dims(image, <your desired dimension>)
예 (위 링크에서 가져옴) :
x = np.array([1, 2])
print(x.shape) # prints (2,)
그때
y = np.expand_dims(x, axis=0)
수확량
array([[1, 2]])
과
y.shape
준다
(1, 2)
답변
올바른 크기의 배열을 미리 만들어 채울 수 있습니다.
frames = np.empty((480, 640, 3, 100))
for k in xrange(nframes):
frames[:,:,:,k] = cv2.imread('frame_{}.jpg'.format(k))
프레임이 특정 방식으로 이름이 지정된 개별 jpg 파일 인 경우 (예 : frame_0.jpg, frame_1.jpg 등).
참고로 (nframes, 480,640,3)
, 대신 모양 배열을 사용하는 것을 고려할 수 있습니다 .
답변
Pythonic
X = X[:, :, None]
이는
X = X[:, :, numpy.newaxis]
과
X = numpy.expand_dims(X, axis=-1)
그러나 이미지 스택에 대해 명시 적으로 질문 하고 있으므로 루프에서 수집 한 list
이미지 를 스택하는 것이 좋습니다 np.stack([X1, X2, X3])
.
치수 순서가 마음에 들지 않으면 재정렬 할 수 있습니다. np.transpose()
답변
다음을 사용 np.concatenate()
하여 axis
추가 할 항목 을 지정할 수 있습니다 np.newaxis
.
import numpy as np
movie = np.concatenate((img1[:,np.newaxis], img2[:,np.newaxis]), axis=3)
여러 파일에서 읽는 경우 :
import glob
movie = np.concatenate([cv2.imread(p)[:,np.newaxis] for p in glob.glob('*.jpg')], axis=3)
답변
numpy에는 나중에 더 많은 데이터를 추가 할 수있는 구조가 없습니다.
대신 numpy는 모든 데이터를 연속 된 숫자 청크 (기본적으로 C 배열)에 넣고 크기를 조정하려면 데이터를 저장할 새 메모리 청크를 할당해야합니다. Numpy의 속도는 동일한 메모리 청크에있는 numpy 배열의 모든 데이터를 유지할 수 있다는 점에서 비롯됩니다. 예를 들어 수학적 연산은 속도 를 위해 병렬화 될 수 있으며 캐시 미스 가 줄어 듭니다 .
따라서 두 가지 종류의 솔루션이 있습니다.
- numpy 배열에 대한 메모리를 미리 할당하고 JoshAdel의 답변과 같이 값을 입력하거나
- 데이터를 실제로 모두 합쳐야 할 때까지 일반 파이썬 목록에 보관하십시오 (아래 참조).
images = []
for i in range(100):
new_image = # pull image from somewhere
images.append(new_image)
images = np.stack(images, axis=3)
먼저 개별 이미지 배열의 차원을 확장 할 필요가 없으며 예상되는 이미지 수를 미리 알 필요도 없습니다.
답변
reshape 방법을 사용하는 접근법 1과 동일한 결과를 생성하는 np.newaxis 방법을 사용하는 접근법 2를 고려하십시오.
#Lets suppose, we have:
x = [1,2,3,4,5,6,7,8,9]
print('I. x',x)
xNpArr = np.array(x)
print('II. xNpArr',xNpArr)
print('III. xNpArr', xNpArr.shape)
xNpArr_3x3 = xNpArr.reshape((3,3))
print('IV. xNpArr_3x3.shape', xNpArr_3x3.shape)
print('V. xNpArr_3x3', xNpArr_3x3)
#Approach 1 with reshape method
xNpArrRs_1x3x3x1 = xNpArr_3x3.reshape((1,3,3,1))
print('VI. xNpArrRs_1x3x3x1.shape', xNpArrRs_1x3x3x1.shape)
print('VII. xNpArrRs_1x3x3x1', xNpArrRs_1x3x3x1)
#Approach 2 with np.newaxis method
xNpArrNa_1x3x3x1 = xNpArr_3x3[np.newaxis, ..., np.newaxis]
print('VIII. xNpArrNa_1x3x3x1.shape', xNpArrNa_1x3x3x1.shape)
print('IX. xNpArrNa_1x3x3x1', xNpArrNa_1x3x3x1)
결과는 다음과 같습니다.
I. x [1, 2, 3, 4, 5, 6, 7, 8, 9]
II. xNpArr [1 2 3 4 5 6 7 8 9]
III. xNpArr (9,)
IV. xNpArr_3x3.shape (3, 3)
V. xNpArr_3x3 [[1 2 3]
[4 5 6]
[7 8 9]]
VI. xNpArrRs_1x3x3x1.shape (1, 3, 3, 1)
VII. xNpArrRs_1x3x3x1 [[[[1]
[2]
[3]]
[[4]
[5]
[6]]
[[7]
[8]
[9]]]]
VIII. xNpArrNa_1x3x3x1.shape (1, 3, 3, 1)
IX. xNpArrNa_1x3x3x1 [[[[1]
[2]
[3]]
[[4]
[5]
[6]]
[[7]
[8]
[9]]]]