복붙노트

[PYTHON] 수십 개의 배열에 대한 가장 빠른 저장 및로드 옵션

PYTHON

수십 개의 배열에 대한 가장 빠른 저장 및로드 옵션

dtype = float 및 shape (1e3, 1e6)의 순서로 2 차원 numpy 배열을 생성하는 스크립트가 있습니다. 지금 당장은 np.save와 np.load를 사용하여 배열에 IO 작업을 수행합니다. 그러나 이러한 함수는 각 배열에 대해 몇 초가 걸립니다. 전체 배열을 저장하고로드하는 더 빠른 방법이 있습니까 (즉, 내용을 가정하지 않고 줄이는 것)? 데이터가 정확하게 유지되는 한 저장하기 전에 배열을 다른 유형으로 변환하는 방법에 대해 열려 있습니다.

해결법

  1. ==============================

    1.정말 큰 배열의 경우 몇 가지 솔루션에 대해 들었습니다. 주로 I / O에서 게으르다.

    정말 큰 배열의 경우 몇 가지 솔루션에 대해 들었습니다. 주로 I / O에서 게으르다.

    NumPy.memmap의 문서에서 :

    h5py doc에서

    이 형식은 다양한 방식으로 데이터를 압축 할 수 있지만 (동일한 I / O 읽기에 대해 더 많은 비트가로드 됨) 데이터가 개별적으로 쿼리하기가 쉽지는 않지만 귀하의 경우 (순전히로드 / 덤프 배열) 효율적일 수 있습니다

  2. ==============================

    2.다음은 PyTables와의 비교입니다.

    다음은 PyTables와의 비교입니다.

    나는 메모리 제한 때문에 int (1e3), int (1e6)까지 올 수 없다. 따라서 더 작은 배열을 사용했습니다.

    data = np.random.random((int(1e3), int(1e5)))
    

    NumPy 저장 :

    %timeit np.save('array.npy', data)
    1 loops, best of 3: 4.26 s per loop
    

    NumPy로드 :

    %timeit data2 = np.load('array.npy')
    1 loops, best of 3: 3.43 s per loop
    

    PyTables 작성 :

    %%timeit
    with tables.open_file('array.tbl', 'w') as h5_file:
        h5_file.create_array('/', 'data', data)
    
    1 loops, best of 3: 4.16 s per loop
    

    PyTables 독서 :

     %%timeit
     with tables.open_file('array.tbl', 'r') as h5_file:
          data2 = h5_file.root.data.read()
    
     1 loops, best of 3: 3.51 s per loop
    

    숫자는 매우 유사합니다. 그래서 실제 이득은 위대한 PyTables입니다. 하지만 우리는 SSD의 최대 쓰기 및 읽기 속도에 매우 가깝습니다.

    쓰기:

    Maximum write speed: 241.6 MB/s
    PyTables write speed: 183.4 MB/s
    

    독서:

    Maximum read speed: 250.2
    PyTables read speed: 217.4
    

    압축은 데이터의 임의성으로 인해 실제로 도움이되지 않습니다.

    %%timeit
    FILTERS = tables.Filters(complib='blosc', complevel=5)
    with tables.open_file('array.tbl', mode='w', filters=FILTERS) as h5_file:
        h5_file.create_carray('/', 'data', obj=data)
    1 loops, best of 3: 4.08 s per loop
    

    압축 된 데이터 읽기가 조금 느려집니다.

    %%timeit
    with tables.open_file('array.tbl', 'r') as h5_file:
        data2 = h5_file.root.data.read()
    
    1 loops, best of 3: 4.01 s per loop
    

    이는 일반 데이터의 경우와 다릅니다.

     reg_data = np.ones((int(1e3), int(1e5)))
    

    쓰기가 훨씬 빠릅니다.

    %%timeit
    FILTERS = tables.Filters(complib='blosc', complevel=5)
    with tables.open_file('array.tbl', mode='w', filters=FILTERS) as h5_file:
        h5_file.create_carray('/', 'reg_data', obj=reg_data)
    

    1 루프, 3 개 중 최고 : 루프 당 849ms

    독서에서도 마찬가지입니다.

    %%timeit
    with tables.open_file('array.tbl', 'r') as h5_file:
        reg_data2 = h5_file.root.reg_data.read()
    
    1 loops, best of 3: 1.7 s per loop
    

    결론 : 데이터를 정규화할수록 PyTables를 사용하는 것이 더 빠릅니다.

  3. ==============================

    3.내 경험에 따르면 np.save () 및 np.load ()는 하드 디스크와 메모리 사이의 데이터를 지금까지 전송할 때 가장 빠른 솔루션입니다. 나는이 결론을 깨닫기 전에 데이터베이스와 HDFS 시스템에 내 데이터 로딩을 크게 의지했습니다. 내 검사 결과는 다음과 같습니다. 데이터베이스 데이터로드 (하드 디스크에서 메모리로) 대역폭은 약 50 MBps (Byets / Second) 일 수 있지만 np.load () 대역폭은 하드 디스크 최대 대역폭 인 2GBps (Byets / Second)와 거의 같습니다. 두 테스트 환경 모두 가장 간단한 데이터 구조를 사용합니다.

    내 경험에 따르면 np.save () 및 np.load ()는 하드 디스크와 메모리 사이의 데이터를 지금까지 전송할 때 가장 빠른 솔루션입니다. 나는이 결론을 깨닫기 전에 데이터베이스와 HDFS 시스템에 내 데이터 로딩을 크게 의지했습니다. 내 검사 결과는 다음과 같습니다. 데이터베이스 데이터로드 (하드 디스크에서 메모리로) 대역폭은 약 50 MBps (Byets / Second) 일 수 있지만 np.load () 대역폭은 하드 디스크 최대 대역폭 인 2GBps (Byets / Second)와 거의 같습니다. 두 테스트 환경 모두 가장 간단한 데이터 구조를 사용합니다.

    그리고 모양이있는 배열을로드하는 데 몇 초를 사용하는 것은 문제가되지 않는다고 생각합니다. (1e3, 1e6). 예 : 배열 모양이 (1000, 1000000)이고 데이터 유형이 float128이면 순수 데이터 크기는 (128/8) * 1000 * 1,000,000 = 16,000,000,000 = 16GBytes입니다. 4 초가 걸리면 그런 다음 데이터로드 대역폭은 16GBytes / 4Seconds = 4GBps입니다. SATA3 최대 대역폭은 600MBps = 0.6GBps이고 데이터로드 대역폭은 이미 6 배이며 데이터로드 성능은 DDR의 최대 대역폭과 거의 경쟁 할 수 있습니다.

    그래서 마지막 결론은 다음과 같습니다.

    파이썬 피클을 사용하지 마십시오. 데이터베이스를 사용하지 마십시오. np.save ()와 np.load ()를 사용할 수 있다면 큰 데이터 시스템을 사용하여 데이터를 하드 디스크에 저장하지 마십시오. 이 두 기능은 지금까지 하드 디스크와 메모리간에 데이터를 전송하는 가장 빠른 솔루션입니다.

    또한 HDF5를 테스트 한 결과, np.load () 및 np.save ()보다 속도가 느린 것으로 확인되었으므로 platfrom에 충분한 DDR 메모리가있는 경우 np.save () 및 np.load ()를 사용하십시오.

  4. from https://stackoverflow.com/questions/30329726/fastest-save-and-load-options-for-a-numpy-array by cc-by-sa and MIT license