2017-10-13 13 views
0

RAM (~ 100G)에 비해 너무 큰 numpy 배열의 평균을 계산할 때 문제가 있습니다.hdf5 파일에서 memmapped 한 큰 숫자 배열의 평균을 계산하십시오.


나는 np.memmap를 사용을 검토 한 결과,하지만 불행히도 내 배열은 HDF5 파일에 데이터 세트로 저장됩니다. 그리고 내가 시도한 것을 기반으로, np.memmap은 hdf5 데이터 세트를 입력으로 받아들이지 않습니다.
TypeError: coercing to Unicode: need string or buffer, Dataset found

np.mean을 효율적으로 디스크에서 메모리 매핑 된 배열에 호출하려면 어떻게해야합니까? 물론 각 부분이 메모리에 들어 맞는 부분의 데이터 세트를 반복 할 수 있습니다.
그러나이 방법은 해결 방법과 너무 흡사하며 최상의 성능을 얻을 수 있는지 확실하지 않습니다.


는 여기에 몇 가지 예제 코드입니다 :

data = np.randint(0, 255, 100000*10*10*10, dtype=np.uint8) 
data.reshape((100000,10,10,10)) # typically lot larger, ~100G 

hdf5_file = h5py.File('data.h5', 'w') 
hdf5_file.create_dataset('x', data=data, dtype='uint8') 

def get_mean_image(filepath): 
    """ 
    Returns the mean_array of a dataset. 
    """ 
    f = h5py.File(filepath, "r") 
    xs_mean = np.mean(f['x'], axis=0) # memory error with large enough array 

    return xs_mean 

xs_mean = get_mean_image('./data.h5') 
+1

내가이가'h5py' 데이터 세트의 읽기 청크 분할 할 앞서 갈 것. 그 일을하십시오. 그런 다음 반복을 통해 실제로 시간이 소요되는지 테스트 할 수 있습니다. 대규모 배열의 경우 메모리 관리 비용이 반복 비용보다 클 수 있습니다. – hpaulj

+0

네 말이 맞아, 실제로 그렇게 많은 비용이 들지는 않아. 유일한 단점은 코딩해야하는 루프이므로 너무 우아하지 않습니다. 고맙습니다! – 0vbb

답변

1

가 hpaulj이 코멘트에 제안한 것처럼, 난 그냥 여러 단계로 평균 계산을 분할했습니다.
여기에 누군가를 위해 유용 할 수 있다면 내 (간체) 코드입니다 :

def get_mean_image(filepath): 
    """ 
    Returns the mean_image of a xs dataset. 
    :param str filepath: Filepath of the data upon which the mean_image should be calculated. 
    :return: ndarray xs_mean: mean_image of the x dataset. 
    """ 
    f = h5py.File(filepath, "r") 

    # check available memory and divide the mean calculation in steps 
    total_memory = 0.5 * psutil.virtual_memory() # In bytes. Take 1/2 of what is available, just to make sure. 
    filesize = os.path.getsize(filepath) 
    steps = int(np.ceil(filesize/total_memory)) 
    n_rows = f['x'].shape[0] 
    stepsize = int(n_rows/float(steps)) 

    xs_mean_arr = None 
    for i in xrange(steps): 
     if xs_mean_arr is None: # create xs_mean_arr that stores intermediate mean_temp results 
      xs_mean_arr = np.zeros((steps,) + f['x'].shape[1:], dtype=np.float64) 

     if i == steps-1: # for the last step, calculate mean till the end of the file 
      xs_mean_temp = np.mean(f['x'][i * stepsize: n_rows], axis=0, dtype=np.float64) 
     else: 
      xs_mean_temp = np.mean(f['x'][i*stepsize : (i+1) * stepsize], axis=0, dtype=np.float64) 
     xs_mean_arr[i] = xs_mean_temp 

    xs_mean = np.mean(xs_mean_arr, axis=0, dtype=np.float64).astype(np.float32) 

    return xs_mean 
+0

평균의 평균은 모든 버킷이 동일한 크기 일 때 참값과 같습니다. 마지막 양동이가 아니므로 결과가 약간 비뚤어집니다. – pvlkmrv