2013-03-12 1 views
4

지금 당장은 매우 큰 2D numpy 배열을 만들고 numpy.savetxt를 사용하여 탭으로 구분 된 텍스트 파일로 저장하는 파이썬 프로그램이 있습니다. numpy 배열에는 float 만 포함됩니다. 그런 다음 별도의 C++ 프로그램에서 한 번에 한 행씩 파일을 읽습니다.파이썬 - 파일에 numpy 배열 저장 (가장 작은 크기 가능)

나는이 두 프로그램 사이를 통과하는 파일의 크기를 줄이기 위해 코드를 가능한 한 변경하지 않고 동일한 작업을 수행하는 방법을 찾고자합니다.

numpy.savetxt를 사용하여 텍스트 파일 대신 압축 .gz 파일을 저장할 수 있음을 발견했습니다. 이렇게하면 파일 크기가 ~ 2MB에서 ~ 100KB로 줄어 듭니다.

더 좋은 방법이 있나요? 공간을 절약하기 위해 numpy 배열을 파일에 바이너리로 쓸 수 있습니까? 그렇다면 어떻게하면 C++ 프로그램으로 읽을 수 있을까요?

도움 주셔서 감사합니다. 내가 얻을 수있는 지침에 감사드립니다.

편집 :

제로의 많은 내가 어떻게 든이 생각을 악용 작은 파일을 생성 할 수있는 방법 확실하지 않다가합니다 (NumPy와 배열에있는 값의 아마 70 %는 0.0000을하는) 것을 내 C++ 프로그램을 읽을 수 있습니다

+0

그냥 생각해보십시오. 작성해야합니까? 프로그램이 동시에 실행되는 경우 (또는 동시에 실행되도록 만들 수있는 경우) 여러 가지 방법 중 하나를 사용하여 데이터를 서로간에 스트리밍 할 수 있습니다. 명명 된 파이프, TCP 소켓, 공유 메모리 등 –

답변

3

0이 많으므로 양식에 0이 아닌 요소 (색인, 숫자) 만 쓸 수 있습니다. 이제 당신은 단지 데이터의 수가 적은

In [11]: x, y = a.nonzero() 

In [12]: zip(x,y) 
Out[12]: [(3, 1), (7, 4), (9, 0)] 

In [13]: nonzero = zip(x,y) 

:

In [5]: a = np.zeros((10, 10)) 

In [6]: a 
Out[6]: 
array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]) 

In [7]: a[3,1] = 2.0 

In [8]: a[7,4] = 17.0 

In [9]: a[9,0] = 1.5 

첫째, 흥미로운 숫자와 그들의 인덱스를 분리 :

하면 0이 아닌 숫자 소량의 배열이 있다고 가정 요소는 왼쪽.가장 쉬운 것은 텍스트 파일에 기록하는 것입니다

In [17]: with open('numbers.txt', 'w+') as outf: 
    ....:  for r, k in nonzero: 
    ....:   outf.write('{:d} {:d} {:g}\n'.format(r, k, a[r,k])) 
    ....:   

In [18]: cat numbers.txt 
3 1 2 
7 4 17 
9 0 1.5 

이 또한 당신에게 데이터를 안구 할 수있는 기회를 제공합니다. C++ 프로그램에서는 fscanf으로이 데이터를 읽을 수 있습니다.

하지만 당신은 더 struct 사용하여 이진 데이터를 작성하여 크기를 줄일 수 있습니다 :

In [17]: import struct 

In [19]: c = struct.Struct('=IId') 

In [20]: with open('numbers.bin', 'w+') as outf: 
    ....:  for r, k in nonzero: 
    ....:   outf.write(c.pack(r, k, a[r,k])) 

Struct 생성자에 대한 인수는 의미; 원시 날짜 형식 '='을 사용하십시오. 첫 번째 및 두 번째 데이터 요소는 부호없는 정수 'I'이고 세 번째 요소는 두 배 'd'입니다.

C++ 프로그램에서이 데이터는 바이너리 데이터로 포장 된 struct으로 가장 잘 읽을 수 있습니다.

편집 : 2D 배열에 대한 답변이 업데이트되었습니다.

+0

배열은 2 차원이지만 플랫 배열을 고려하여 단일 인덱스를 사용하여 0이 아닌 요소를 참조 할 수 있습니다. – Dave

+0

2D 배열임을 간과했습니다. 죄송합니다. –

+0

둘 다 색인을 제공하도록 코드를 조정하는 방법이 있나요 (2D 배열이므로). 아니면 다른 방법으로 루프를 추가하고 있습니까? 매우 철저한 답장을 보내 주셔서 감사합니다. – user1764386

0

pythonc++에 대해 추가 패키지를 설치하는 데 신경 쓸 필요가 없다면 [BSON][1] (이진 JSON)을 사용할 수 있습니다.

+1

BSON 파일은 심지어 저자에 따르면, 드물게 동등한 JSON 파일보다 작습니다. 그것은 장점이 있지만 그 사이에 공간을 절약하는 것은 아닙니다. – delnan

+0

고마워, 잘 모름 – shx2

1

numpy.ndarray.tofilenumpy.fromfile은 파이썬에서 직접 바이너리 출력/입력하는 데 유용합니다. std::ostream::writestd::istream::read은 C++의 이진 출력/입력에 유용합니다.

데이터가 한 시스템에서 다른 시스템으로 전송되는 경우 엔디안에주의해야합니다.

+0

C++에서'ndarray.tofile'을 사용하여 작성된 파일을 읽는 방법을 설명 할 수 있습니까? – shx2

+0

ndarray.tofile()을 사용할 때 결과 파일은 실제로 numpy.savetxt를 사용할 때보 다 약간 큽니다. 순수한 바이너리를 출력하기 위해 제가 놓칠지도 모르는 논의가 있습니까? – user1764386

+0

엔디 언 : http://stackoverflow.com/questions/13672597/numpys-tostring-fromstring-what-do-i-need-to-specify-to-restore-the-array –

3

endianness 등에 대해 걱정할 필요가 없다면, @ unutbu의 대답과 @ jorgeca의 설명에서 설명한 것처럼 numpy.savez을 사용하는 것이 가장 좋습니다 : numpy's tostring/fromstring --- what do I need to specify to restore the array.

결과 크기가 작지 않은 경우 항상 zlib (파이썬 측에 : import zlib, C++ 측에 구현이 존재 함)이 있습니다.

대체 방법으로는 hdf5 형식을 사용하는 것이 좋습니다. 디스크의 파일 크기를 반드시 줄이지는 않지만 저장 /로드 속도가 빨라집니다 (이 형식은 대형 데이터 배열 용으로 설계된 것입니다). hdf5에 대한 파이썬과 C++ 리더/라이터가 있습니다.

+0

여기 뭔가를 오해하고있는 것처럼 보입니다. numpy.savez를 사용하면 내 배열의 zip이 저장되지만 압축되지 않으므로 크기가 작아지지 않습니다. numpy.savetxt (파일을 ~ 100kB로 압축)에서 .gz 확장자를 지정하는 대신이를 수행하는 것이 유리합니까? 도움을 주셔서 감사합니다. – user1764386

+0

'save/savez '의 장점은 주로 이식성입니다. 저장 한 아키텍처와 동일한 아키텍처에서만 파일을로드 할 것이라 확신하는 경우이 파일들을 신경 쓰지 않아도됩니다. 'hdf5'는 여전히 더 나은 옵션 인 IMO입니다 --- 당신이하고있는 것이 던진 one 타이머가 아니라면. –

1

hdf5 파일을 사용하면 h5py를 통해 사용하기가 정말 쉽고 플래그 설정 압축을 사용할 수 있습니다. hdf5에는 C++ 인터페이스도 있습니다.

관련 문제