2015-01-18 1 views
1

매우 큰 울퉁불퉁 한 행렬의 평균 (무시한 값)을 얻으려고합니다.500 개의 큰 numpy 행렬의 np.nanmean

X=np.load('my_matrix_1.npy', mmap_mode='r') 

을 그리고 난 일부 라인을 읽을 수 있습니다 : 나는 같은 것을, 너무 많은 메모리를 차지하지 않고 그들에로드 할 수 있습니다 알고 있습니다.

for chunk in chunks: 
    chunk_to_mean = [] 
    for matrix in matrices: 
      X=np.load(matrix, mmap_mode='r') 
      chuck_to_mean.append(X) 
      del X 
    matrix[chunk] = np.nanmean(chunk_to_mean) 

그러나, 그것은 보인다 : 나는이 같은

그래서 뭔가를 각 매트릭스에서 한 번에 읽기 1000 선을 생각하고 유모가 행렬의 크기가 사람의 말은 저장되었다 두 번째로 메모리 할당 오류가 발생합니다. 메모리 매핑을 사용하여 무언가를로드하려고해도 삭제하더라도 마찬가지입니다. 누구든지이 문제를 해결하는 방법을 알고 있습니까, 아니면 어떻게 할 수 있을지 더 잘 알고 있습니까?

답변

0

이 코드에는 몇 가지 문제가 있습니다. 첫 번째는 chunk_to_mean = [] 배열을 만듭니다. 그러나 배열에 numpy 배열을 요소로 추가하면 numpy 배열 목록이되지만 np.nanmean은 배열 목록을 사용하지 않고 np.array를 사용합니다.

두 번째는 사전이 있고 문자열을 사용하여 배열을 지정하거나 목록이 있고 int를 사용해야한다는 것입니다. 따라서 chunk[matrix]은 의미가 없습니다.

두 가지 옵션이 있습니다. 모든 청크의 크기가 같으면 각 행렬에 대해 np.nanmean을 취한 다음 결과 목록의 평균을 취할 수 있습니다. 이것은 테스트 작품입니다

results = [] 
for chunk in chunks: 
    for i in range(len(matrices)): 
     X=np.load(matrix, mmap_mode='r') 
     if i==1: 
      all_matrices = np.array(X) 
     else: 
      np.concatenate((all_matrices, np.array(X), axis=0) # check the concat axis!! 
     del X 
    results.append(np.nanmean(all_matrices)) 
+0

개체를 삭제하지 않고 메모리 맵을 두 번 이상 만들면 메모리 할당 문제가 발생하므로 del X를 사용해야합니다. 하지만, 내가 말했듯이, 첫 번째 반복 이후 두 번째 반복에서 실패하고 메모리 오류가 발생합니다. 메모리가 부족하기 때문에가 아니라 메모리를 할당 할 수 없기 때문입니다. 그 중 어느 것도 작동하지 않는 이유가 있습니다. –

+0

Ok - 문제에 대한 아이디어가 있다고 생각합니다. 요점은 배열이 배열에 대한 포인터로 취급된다는 것입니다. 따라서 X를 추가 할 때는 파일을 추가하지 않고 파일에 대한 포인터를 추가합니다. 이 문제를 해결하려면 먼저 행렬을 복사하십시오. np로 이것을하는 좋은 방법. 배열이'np.array (orig_pointer)'에있다 -이 호출은 데이터를 복사 할 것이고, 당신은 모든 np. * 기능을 사용할 수 있어야한다. – cleros

+0

'np.array (X)'호출을 참조하십시오. 연결시 X 사본을 만들기 위해 두 번째 버전을 업데이트했습니다. – cleros

0

: 당신이 가중 평균을 원하는 경우

results = [] 
for chunk in chunks: 
    chunk_to_mean = [] 
    for matrix in matrices: 
     X=np.load(matrix, mmap_mode='r') 
     chuck_to_mean.append(np.nanmean(X)) 
     del X # why do you need this?? This is python - it has garbage collection! 
    results.append(np.nanmean(np.array(chunk_to_mean))) 

다른 옵션은, 행렬을 연결 한 다음 해당의 np.nanmean을하는 것입니다. 한 번에 행렬의 한 행을 읽는 것만으로 매우 큰 행렬에서 작동해야합니다. 평균 행렬을 메모리에 보유 할 수 있으면 실행됩니다.

def average_subject_real(subject): 
    matrix = np.load('graph_matrix_%s_1.npy' %(subject), mmap_mode = 'r') 
    matrix_size = matrix.shape[0] 
    del matrix 
    average_matrix = np.zeros((matrix_size,matrix_size)) 
    for line in range(matrix_size): 
     temp_array = [] 
     for i in range(1,5): 
      matrix = np.load('graph_matrix_%s_%s.npy' %(subject,i), mmap_mode = 'r') 
      matrix = np.array(matrix[line]) # the copying happens here 
     temp_array.append(matrix) 
     del matrix 
     average_matrix[line] = np.nanmean(temp_array,axis=0) 
    np.save('graph_matrix_%s_average.npy' %(subject),arr=average_matrix) 
+0

이전에 문제였던 점은 cleros가 지적했듯이 배열을 복사해야합니다. 그렇지 않으면 포인터가 여전히 존재하며 새로운 메모리 매핑 된 배열 객체를 얻을 수 없습니다. 모두의 도움에 감사 드리며 지금 운영 중입니다! –

관련 문제