2017-03-29 3 views
0

각 행이 이미지의 평평한 버전 인 곳에서 numpy 배열로 hdf 파일 컬렉션을 빠르게 설정하는 방법을 찾고 있습니다. 정확히 의미하는 것 :hdf에서 numpy로 ndarray로 - 빠른 방법

내 hdf 파일은 다른 정보 옆에 프레임 당 이미지를 저장합니다. 각 파일에는 512x424 이미지가있는 51 개의 프레임이 있습니다. 이제 300+ hdf 파일이 있고 모든 이미지의 모든 프레임이 하나의 numpy ndarray에 저장되는 프레임 당 하나의 단일 벡터로 이미지 픽셀을 저장하고 싶습니다. 내가 지금까지 가지고 무엇

Visualized process of transforming many hdf files to one numpy array

가 매우 느린 방법이며, 사실은 내가 더 빨리 만들 수있는 방법 아무 생각이 : 다음 그림을 이해하는 데 도움이됩니다. 문제는 내가 생각하기에 최종 배열이 너무 자주 호출된다는 것입니다. 첫 번째 파일은 배열에 매우 빠르게로드되지만 속도는 빠르게 감소합니다.

내 현재 코드 (현재 HDF 파일의 수를 인쇄하여 관찰) : 자세한 내용은

os.chdir(os.getcwd()+"\\datasets") 

# predefine first row to use vstack later 
numpy_data = np.ndarray((1,217088)) 

# search for all .hdf files 
for idx, file in enumerate(glob.glob("*.hdf5")): 
    f = h5py.File(file, 'r') 
    # load all img data to imgs (=ndarray, but not flattened) 
    imgs = f['img']['data'][:] 

    # iterate over all frames (50) 
    for frame in range(0, imgs.shape[0]): 
    print("processing {}/{} (file/frame)".format(idx+1,frame+1)) 
    data = np.array(imgs[frame].flatten()) 
    numpy_data = np.vstack((numpy_data, data)) 

    # delete first row after another is one is stored 
    if idx == 0 and frame == 0: 
     numpy_data = np.delete(numpy_data, 0,0) 

f.close() 

, 나는 의사 결정 트리 학습이 필요합니다. 내 hdf 파일이 내 RAM보다 크기 때문에 메모리를 절약 할 수있는 배열로 변환하여 더 적합하다고 생각합니다.

모든 입력에 감사드립니다. 나는 생각하지 않는다

+0

알고리즘에 한 번에 두 개 이상의 프레임이 필요합니까? 나는 속도 저하가 vstack에 대한 모든 호출에서 비롯된 것이라는 것을 추측하고 있습니다. 그런 식으로는 아무 것도 할 필요가 없을 것입니다. – Elliot

+0

또한 if if idx == 0 및 frame == 0 :'조건으로 어떤 일이 일어나고 있는지 잘 모르겠습니다. 난 당신이 그것에서 0x217088 요소 배열을 받고 있다고 생각합니다. – Elliot

+0

불행히도 모든 기능 공간을 사용하는 임의의 forrests를 사용하려고합니다. 어쩌면 scikit 배울 수있는 방법에 대한 또 다른 옵션이 있지만, 나는 그런 인식하지 못합니다. – muleque

답변

1

당신은 정말 RAM에 모든 이미지를로드하는 대신 하나의 HDF5 파일을 사용하지 wan't합니까? 실수를하지 않으면 HDF5 파일에 액세스하는 것이 아주 빠를 수 있습니다 (unnessesary fancy indexing, 부적절한 chache-size).

os.chdir(os.getcwd()+"\\datasets") 
img_per_file=51 

# get all HDF5-Files 
files=[] 
for idx, file in enumerate(glob.glob("*.hdf5")): 
    files.append(file) 

# allocate memory for your final Array (change the datatype if your images have some other type) 
numpy_data=np.empty((len(files)*img_per_file,217088),dtype=np.uint8) 

# Now read all the data 
ii=0 
for i in range(0,len(files)): 
    f = h5py.File(files[0], 'r') 
    imgs = f['img']['data'][:] 
    f.close() 
    numpy_data[ii:ii+img_per_file,:]=imgs.reshape((img_per_file,217088)) 
    ii=ii+img_per_file 

단일 HDF5 파일에 데이터를 쓰는 것은 매우 유사하다 :

f_out=h5py.File(File_Name_HDF5_out,'w') 
# create the dataset (change the datatype if your images have some other type) 
dset_out = f_out.create_dataset(Dataset_Name_out, ((len(files)*img_per_file,217088), chunks=(1,217088),dtype='uint8') 

# Now read all the data 
ii=0 
for i in range(0,len(files)): 
    f = h5py.File(files[0], 'r') 
    imgs = f['img']['data'][:] 
    f.close() 
    dset_out[ii:ii+img_per_file,:]=imgs.reshape((img_per_file,217088)) 
    ii=ii+img_per_file 

f_out.close() 

하는 경우에만 wan't 경우에는 NumPy와 방향을 wan't 경우 이 가능성이 될 것입니다 이후 전체 이미지에 액세스하려면 청크 크기가 괜찮습니다. 그렇지 않다면 필요에 맞게 변경해야합니다. HDF5-파일에 액세스 할 때 무엇을해야

:

  • 사용자의 요구에 맞는 청크 크기를 사용합니다.

  • 올바른 청크 크기를 설정하십시오. 이것은 h5py 로우 레벨 api 또는 h5py_cache를 사용하여 수행 할 수 있습니다. https://pypi.python.org/pypi/h5py-cache/1.0

  • 멋진 색인 생성을 피하십시오. 데이터 세트에 n 차원이있는 경우 반환 된 배열에도 n 차원이있는 방식으로 액세스합니다.

    # Chunk size is [50,50] and we iterate over the first dimension 
    numpyArray=h5_dset[i,:] #slow 
    numpyArray=np.squeeze(h5_dset[i:i+1,:]) #does the same but is much faster 
    

편집 이것은 memmaped NumPy와 배열에 데이터를 읽는 방법을 보여줍니다. 당신의 방법은 np.float32 형식의 데이터를 기대한다고 생각합니다. 다른 https://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html#numpy.memmap

numpy_data = np.memmap('Your_Data.npy', dtype='np.float32', mode='w+', shape=((len(files)*img_per_file,217088))) 

모든 것이 동일하게 유지 될 수있다. 작동하는 경우 하드 디스크 대신 SSD를 사용하는 것이 좋습니다.

+0

이 데이터와 함께 임의의 forrests/Decision 트리를 사용할 예정이며이 메서드는 전체 데이터를 한 번에 필요로한다는 것을 알았습니다. 그래서 내가 chunked 버전으로 갈 수 없다고 생각합니다. 또는 hdf 파일을 chunking하는 것이 어떻게 작동하는지 이해하지 못합니까? – muleque

+0

좋아, 내 첫 제안 (numpy 배열의 데이터 읽기 만)이 효과가 있습니까? – max9111

+0

내가 요청한 목적을 위해 잘 작동합니다. 그러나 나는 학습 알고리즘 (결정 트리)에 내 데이터를 어떻게 공급할 것인지 모르겠다. 이것은 내 데이터 세트를 26GB에서 3GB로 줄였습니다. 이것은 실제 메모리 세트의 일부 였기 때문에 ~ 20 배 더 커졌습니다. 핵심 메모리에서 빠져 나가지 않고 처리하는 방법을 모르겠습니다. – muleque

1

당신은

이상
imgs = f['img']['data'][:] 

를 반복하고 각각의 2 차원 배열을 바꿀 필요가있다. 모든 것을 바꿀뿐입니다. (51, 512, 424)

imgs.reshape(51, 512*424) 

는 2D 동일해야 : 나는 당신의 설명 권리를 이해한다면, imgs는 차원 배열입니다.

루프해야하는 경우 vstack (또는 더 큰 배열을 만들기 위해 일부 변형)을 사용하지 마십시오. 하나는 천천히, 두 번째는 초기 '더미'항목을 지우는 것입니다. 그것은 한 번에 여러 작업을 할 수 있도록 최종

alist = [] 
for frame.... 
    alist.append(data) 
data_array = np.vstack(alist) 

vstack (가족)에서리스트에 추가를 사용하고, 한 번에 적재 할은, 입력으로 배열의 목록을합니다. List append는 반복 수행시 훨씬 빠릅니다.

나는 하나의 배열에 물건을 넣는 것이 도움이되는지 질문합니다. hdf5 파일의 크기가 다운로드 한 배열의 크기와 어떤 관련이 있는지 정확히 알지 못하지만 크기가 같을 것으로 예상됩니다. 300 개의 파일을 모두 메모리에로드하려고하면 작동하지 않을 수 있습니다. 그게 픽셀의 3G인가요?

개별 파일의 경우 h5py에는 너무 커서 메모리에 들어갈 수있는 배열 청크를로드 할 수 있습니다. 이는 문제가 다른 방향으로 진행되는 경우가 많음을 나타내며 파일에 적합하지 않습니다.

Is it possible to load large data directly into numpy int8 array using h5py?