2016-08-23 5 views
0

2 차원 배열을 포함하는 메모리 맵이 있는데이 배열을 사용하여 배열을 만들고 싶습니다. 이상적으로, 관련 배열이 커질 수 있기 때문에 복사를 피하고 싶습니다. 나는 많은 frombuffer을 사용하지 않은Numpy 2D-Array from Buffer?

n_bytes = 10000 
tagname = "Some Tag from external System" 
map = mmap.mmap(-1, n_bytes, tagname) 
offsets = [0, 5000] 

columns = [] 
for offset in offsets: 
    #type and count vary in the real code, but for this dummy code I simply made them up. But I know the count and type for every column. 
    np_type = np.dtype('f4') 
    column_data = np.frombuffer(map, np_type, count=500, offset=offset) 
    columns.append(column_data) 

# this line seems to copy the data, which I would like to avoid 
data = np.array(columns).T 
+0

는 큰 1D 배열로 전체 파일을 읽는 시도했다 후 2 차원 배열을 바꿀? – kennytm

+0

최종 배열의 크기를 미리 알고 있습니까? – Julien

+0

@kennytm 데이터는 버퍼 메소드에서 표현할 수없는 열 (예 : 첫 번째 블록은 float, 두 번째는 int)마다 다른 dtyp을 가질 수 있습니다. –

답변

1

하지만 통상적으로 건설 사람과 마찬가지로 나는 그 배열로 np.array 일을 생각 :

내 코드는 다음과 같습니다.

column_data 어레이에는 자체 데이터 버퍼 (사용자가 지정한 mmap)가 있습니다. 그러나 np.array(columns)은 목록의 각 배열에서 값을 읽고 자체 데이터 버퍼를 사용하여 새 배열을 구성합니다.

저는 데이터 버퍼 위치를보고 다른 키 속성을 보려면 x.__array_interface__을 사용하고 싶습니다. columnsdata에 대해 해당 사전을 비교하십시오.

연속 된 블록을 사용하여 mmap에서 2 차원 배열을 생성 할 수 있습니다. 1d frombuffer 어레이를 만들고 reshape 어레이로 만듭니다. transpose도 계속 해당 버퍼를 사용합니다 (F 순서 사용). 슬라이스와 뷰에서도이를 사용합니다.

하지만 조심하지 않으면 데이터를 다른 곳에 넣는 복사본을 빨리 얻을 수 있습니다. 단순히 data1 = data+1이 새로운 배열을 만들거나 사전 인덱싱 data[[1,3,5],:]이됩니다. concatenation과 동일합니다. bytestring 버퍼로부터

2 개 어레이 :

In [534]: x=np.frombuffer(b'abcdef',np.uint8) 
In [535]: y=np.frombuffer(b'ghijkl',np.uint8) 

x,y,z 그들에게

In [536]: z=np.array((x,y)) 

In [538]: x.__array_interface__ 
Out[538]: 
{'data': (3013090040, True), 
'descr': [('', '|u1')], 
'shape': (6,), 
'strides': None, 
'typestr': '|u1', 
'version': 3} 
In [539]: y.__array_interface__['data'] 
Out[539]: (3013089608, True) 
In [540]: z.__array_interface__['data'] 
Out[540]: (180817384, False) 

데이터 버퍼 위치를 접합하여 새로운 배열을 완전히 다르다

그러나 고쳐 x 아무튼 대한 데이터 변경하기

In [541]: x.reshape(2,3).__array_interface__['data'] 
Out[541]: (3013090040, True) 

도 차원이

In [542]: x.reshape(2,3).T.__array_interface__ 
Out[542]: 
{'data': (3013090040, True), 
'descr': [('', '|u1')], 
'shape': (3, 2), 
'strides': (1, 3), 
'typestr': '|u1', 
'version': 3} 

같은 데이터를 트랜스 않습니다, 다른보기

In [544]: x 
Out[544]: array([ 97, 98, 99, 100, 101, 102], dtype=uint8) 
In [545]: x.reshape(2,3).T 
Out[545]: 
array([[ 97, 100], 
     [ 98, 101], 
     [ 99, 102]], dtype=uint8) 
In [546]: x.reshape(2,3).T.view('S1') 
Out[546]: 
array([[b'a', b'd'], 
     [b'b', b'e'], 
     [b'c', b'f']], 
     dtype='|S1') 
+0

대단히 감사합니다! 열 크기가 다를 때 frombuffer 메서드를 어떻게 사용할 수 있는지 알고 있습니까? 예 : 내 첫 번째 블록에는 f4가 있지만 두 번째 f8은 2 차원 배열을 작성한 후 다시 변형해야합니다. –

+0

구조화 된 배열은 필드에 다른 dtyp을 허용합니다. 그러나 이러한 배열에서'f4' 요소는 별도의 열 ('f4'의 블록,'f8 '의 개별 블록)이 아닌'records'의'f8' 등 옆에 있습니다. 열과 dtypes를 혼합하는 방법을 모르겠습니다. – hpaulj