복사하지 않고 Numpy 배열 연결
Numpy에서 두 개의 배열을 np.append
or로 end-to-end로 연결할 수 있습니다 np.concatenate
.
>>> X = np.array([[1,2,3]])
>>> Y = np.array([[-1,-2,-3],[4,5,6]])
>>> Z = np.append(X, Y, axis=0)
>>> Z
array([[ 1, 2, 3],
[-1, -2, -3],
[ 4, 5, 6]])
그러나 이들은 입력 배열의 사본을 만듭니다.
>>> Z[0,:] = 0
>>> Z
array([[ 0, 0, 0],
[-1, -2, -3],
[ 4, 5, 6]])
>>> X
array([[1, 2, 3]])
복사하지 않고 두 배열을 뷰로 연결하는 방법이 있습니까? np.ndarray
하위 클래스 가 필요 합니까?
Numpy 배열에 속하는 메모리는 연속적이어야합니다. 배열을 별도로 할당하면 메모리에 무작위로 흩어져 뷰 Numpy 배열로 나타낼 방법이 없습니다.
필요한 어레이의 수를 미리 알고 있다면, 대신 미리 할당 한 하나의 큰 어레이로 시작하여 각각의 작은 어레이가 큰 어레이에 대한 뷰가되도록 할 수 있습니다 (예 : 슬라이싱으로 획득).
데이터로 채우기 전에 배열을 초기화하십시오. 원하는 경우 필요한 것보다 더 많은 공간을 할당 할 수 있으며 numpy가 작동하는 방식으로 인해 더 많은 RAM을 차지하지 않습니다.
A = np.zeros(R,C)
A[row] = [data]
메모리는 데이터가 어레이에 입력 된 후에 만 사용됩니다. 두 개를 연결하여 새 배열을 만드는 것은 크기에 관계없이 데이터 집합 (예 : 데이터 집합> 1GB 정도)에서 완료되지 않습니다.
별로 우아하지는 않지만 튜플을 사용하여 배열에 대한 포인터를 저장하는 데 원하는 것에 가까워 질 수 있습니다. 이제 케이스에서 어떻게 사용할지 모르겠지만 이전에 이와 같은 작업을 수행했습니다.
>>> X = np.array([[1,2,3]])
>>> Y = np.array([[-1,-2,-3],[4,5,6]])
>>> z = (X, Y)
>>> z[0][:] = 0
>>> z
(array([[0, 0, 0]]), array([[-1, -2, -3],
[ 4, 5, 6]]))
>>> X
array([[0, 0, 0]])
다음과 같이 배열 배열을 만들 수 있습니다.
>>> from numpy import *
>>> a = array([1.0, 2.0, 3.0])
>>> b = array([4.0, 5.0])
>>> c = array([a, b])
>>> c
array([[ 1. 2. 3.], [ 4. 5.]], dtype=object)
>>> a[0] = 100.0
>>> a
array([ 100., 2., 3.])
>>> c
array([[ 100. 2. 3.], [ 4. 5.]], dtype=object)
>>> c[0][1] = 200.0
>>> a
array([ 100., 200., 3.])
>>> c
array([[ 100. 200. 3.], [ 4. 5.]], dtype=object)
>>> c *= 1000
>>> c
array([[ 100000. 200000. 3000.], [ 4000. 5000.]], dtype=object)
>>> a
array([ 100., 200., 3.])
>>> # Oops! Copies were made...
문제는 브로드 캐스트 작업에서 복사본을 생성한다는 것입니다 (버그처럼 들림).
대답은 Ndarray의 ndarray 행 참조의 다른 대답을 기반으로합니다.
X = np.array([[1,2,3]])
Y = np.array([[-1,-2,-3],[4,5,6]])
Z = np.array([None, None, None])
Z[0] = X[0]
Z[1] = Y[0]
Z[2] = Y[1]
Z[0][0] = 5 # X would be changed as well
print(X)
Output:
array([[5, 2, 3]])
# Let's make it a function!
def concat(X, Y, copy=True):
"""Return an array of references if copy=False"""
if copy is True: # deep copy
return np.append(X, Y, axis=0)
len_x, len_y = len(X), len(Y)
ret = np.array([None for _ in range(len_x + len_y)])
for i in range(len_x):
ret[i] = X[i]
for j in range(len_y):
ret[len_x + j] = Y[j]
return ret
I had the same problem and ended up doing it reversed, after concatenating normally (with copy) I reassigned the original arrays to become views on the concatenated one:
import numpy as np
def concat_no_copy(arrays):
""" Concats the arrays and returns the concatenated array
in addition to the original arrays as views of the concatenated one.
Parameters:
-----------
arrays: list
the list of arrays to concatenate
"""
con = np.concatenate(arrays)
viewarrays = []
for i, arr in enumerate(arrays):
arrnew = con[sum(len(a) for a in arrays[:i]):
sum(len(a) for a in arrays[:i + 1])]
viewarrays.append(arrnew)
assert all(arr == arrnew)
# return the view arrays, replace the old ones with these
return con, viewarrays
You can test it as follows:
def test_concat_no_copy():
arr1 = np.array([0, 1, 2, 3, 4])
arr2 = np.array([5, 6, 7, 8, 9])
arr3 = np.array([10, 11, 12, 13, 14])
arraylist = [arr1, arr2, arr3]
con, newarraylist = concat_no_copy(arraylist)
assert all(con == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14]))
for old, new in zip(arraylist, newarraylist):
assert all(old == new)
참고URL : https://stackoverflow.com/questions/7869095/concatenate-numpy-arrays-without-copying
'developer tip' 카테고리의 다른 글
Subversion 작업 복사본에서 디렉토리 이름을 바꾸는 건전한 방법 (0) | 2020.11.12 |
---|---|
인수 전달 전략-환경 변수 대 명령 줄 (0) | 2020.11.12 |
VisualVM-스레드 상태 (0) | 2020.11.12 |
코드 분석 창이 어디로 갔습니까? (0) | 2020.11.12 |
키보드 단축키로 코드 탐색 (0) | 2020.11.12 |