2012-09-22 2 views
5

나의 주요 목표는 거대한 행렬 행렬에서 중앙값 (열 기준)을 계산하는 것입니다. 예 :Python - 파일에서 열 반복자 가져 오기 (전체 파일을 읽지 않고)

a = numpy.array(([1,1,3,2,7],[4,5,8,2,3],[1,6,9,3,2])) 

numpy.median(a, axis=0) 

Out[38]: array([ 1., 5., 8., 2., 3.]) 

매트릭스 파이썬 메모리 (~ 5 테라 바이트)에 맞게 너무 커서, 그래서 csv 파일에 보관합니다. 그래서 각 열을 실행하고 중간 값을 계산하고 싶습니다.

전체 파일을 읽지 않고도 열 반복기를 사용할 수있는 방법이 있습니까?

매트릭스의 중앙값 계산에 대한 다른 아이디어도 좋습니다. 고맙습니다!

+2

참고 : http://stackoverflow.com/questions/1053928/python-numpy-very-large-matrices –

답변

1

N 개의 빈 파일을 초기화하여 각 열에 하나씩이 작업을 수행합니다. 그런 다음 한 번에 한 행씩 행렬을 읽고 각 열 항목을 올바른 파일로 보냅니다. 전체 행렬을 처리했으면 돌아가서 순차적으로 각 파일의 중앙값을 계산하십시오.

기본적으로 파일 시스템을 사용하여 행렬 전치를 수행합니다. 전치 된 후에는 각 행의 중앙값을 계산하는 것이 쉽습니다. 당신이 (당신은 당신이 할 수있는 것을 의미하는 것) 메모리에 각 열을 맞는 경우

+1

답장을 보내 주셔서 감사합니다.내 매트릭스 크기 ~ 5 테라 바이트입니다, 나는이 일을 할 수있는 충분한 스토리지가없는 것 같아요 : ( – dbaron

3

, 다음이 작동합니다 :

이것은 우리가 얼마나 많은 열을 알아내는 방식으로 작동
import itertools 
import csv 

def columns(file_name): 
    with open(file_name) as file: 
     data = csv.reader(file) 
     columns = len(next(data)) 
    for column in range(columns): 
     with open(file_name) as file: 
      data = csv.reader(file) 
      yield [row[column] for row in data] 

는 다음 파일을 통해 반복 현재 행의 항목을 각 행에서 가져옵니다. 즉, 한 번에 열 크기와 메모리 행 크기를 함께 사용합니다. 꽤 간단한 생성기입니다. 파일을 반복 할 때 루프를 반복 할 때마다 파일을 다시 열어야합니다.

+0

파일을 다시 여는 것이 문제가 있다면, 그냥'for'를 for 루프 바깥으로 옮기고'file.seek 0)'inside. –

+0

@MuMind 다시 여는 대신 좋은 대안이 될 수 있습니다. (어떤 이유로 든 파일 이름이없는 경우를 대비하여 파일 객체를 전달할 수도 있습니다.) –

0

bucketsort를 사용하여 디스크의 각 열을 모두 메모리로 읽어 들이지 않고 정렬 할 수 있습니다. 그런 다음 중간 값을 간단히 선택할 수 있습니다.

또는 awksort 명령을 사용하여 중간 값을 선택하기 전에 열을 분할 한 다음 정렬 할 수 있습니다.

1

내가 잘못 이해하지 않는 한, 당신이 csv 파일로 요청한 것을 직접 할 방법이 없을 것입니다. 문제는 파일이 고정 너비 행을 갖도록 특별히 설계되지 않는 한 모든 파일에 "열"이 있다는 의미가 없음을 의미합니다. CSV 파일은 일반적으로 그렇게 설계되지 않았습니다. 디스크에, 그들은 거대한 문자열에 지나지 것 없다 : 당신이 볼 수 있듯이

>>> import csv 
>>> with open('foo.csv', 'wb') as f: 
...  writer = csv.writer(f) 
...  for i in range(0, 100, 10): 
...   writer.writerow(range(i, i + 10)) 
... 
>>> with open('foo.csv', 'r') as f: 
...  f.read() 
... 
'0,1,2,3,4,5,6,7,8,9\r\n10,11,12,13,14,15,16,17,18,19\r\n20..(output truncated).. 

는, 열 필드가 예상대로 정렬되지 않는다; 두 번째 열은 인덱스 2에서 시작하지만 다음 행에서는 열의 너비가 1 씩 증가하여 정렬을 버립니다. 입력 길이가 다를 때 더욱 그렇습니다. 결론은 csv 리더가 사용하지 않는 데이터를 버리고 전체 파일을 읽어야한다는 것입니다. (걱정하지 않는다면, 그 답입니다. 사용하지 않을 데이터를 버리고, 전체 파일을 한 줄씩 읽으십시오.)

공간을 낭비하지 않고 어떤 데이터도 고정 너비보다 길어지지 않습니다. 너비가 고정 된 필드를 가진 파일을 만들 수 있습니다. 그런 다음 오프셋을 사용하여 찾을 수 있습니다. 하지만 일단 그렇게하면 실제 데이터베이스를 사용할 수도 있습니다. PyTables은 수많은 배열을 저장하기 위해 많은 사람들이 선호하는 것으로 보인다.

+1

+1 이것을 두 번 이상 수행하기 위해 CSV는 형식을 유지하기에 부적절한 선택입니다. –

+0

@sendle DB는 저의 목표입니다. numpy.loadtxt (file_path, usecols = [1,2,3])가 수행 할 작업을 알고 있습니까? 지금은 속임수입니까? – dbaron

+0

@dbaron, "do the trick"이 의미하는 바에 달려 있습니다.'usecols = [1, 2, 3]'가 전체 행렬을 즉시 메모리에로드하는 것을 피할 것이라고 확신합니다. 그래서 그 의미에서 그렇습니다. 나는 또한 전체 파일을 줄 단위로 쓰고, 사용하지 않는 데이터를 버리는 것을 확신합니다. ense, no. – senderle

관련 문제