문제

각각 크기가 약 10Gb인 CSV 데이터 세트가 많이 있습니다.해당 열에서 히스토그램을 생성하고 싶습니다.하지만 numpy에서 이 작업을 수행하는 유일한 방법은 먼저 전체 열을 numpy 배열로 로드한 다음 다음을 호출하는 것 같습니다. numpy.histogram 그 배열에.이는 불필요한 양의 메모리를 소비합니다.

numpy는 온라인 비닝을 지원합니까?나는 내 csv를 한 줄씩 반복하고 값을 읽을 때 값을 저장하는 것을 바라고 있습니다.이렇게 하면 한 번에 최대 한 줄만 메모리에 남게 됩니다.

직접 굴리는 것은 어렵지 않지만 누군가 이미 이 바퀴를 발명한 것인지 궁금합니다.

도움이 되었습니까?

해결책

당신이 말했듯이, 당신 자신을 굴리는 것은 그리 어렵지 않습니다. 파일을 반복 할 때 쓰레기통을 직접 설정하고 재사용해야합니다. 다음은 괜찮은 출발점이어야합니다.

import numpy as np
datamin = -5
datamax = 5
numbins = 20
mybins = np.linspace(datamin, datamax, numbins)
myhist = np.zeros(numbins-1, dtype='int32')
for i in range(100):
    d = np.random.randn(1000,1)
    htemp, jnk = np.histogram(d, mybins)
    myhist += htemp

성능이 큰 파일의 문제가 될 것이라고 생각합니다. 각 라인에서 히스토그램을 호출하는 오버 헤드는 너무 느릴 수 있습니다. @doug의 제안 발전기의 문제는 그 문제를 해결하는 좋은 방법 인 것 같습니다.

다른 팁

값을 직접 구간화하는 방법은 다음과 같습니다.

import numpy as NP

column_of_values = NP.random.randint(10, 99, 10)

# set the bin values:
bins = NP.array([0.0, 20.0, 50.0, 75.0])

binned_values = NP.digitize(column_of_values, bins)

'binned_values'는 column_of_values의 각 값이 속하는 bin의 인덱스를 포함하는 인덱스 배열입니다.

'bincount'는 (분명히) bin 개수를 제공합니다.

NP.bincount(binned_values)

데이터 세트의 크기를 고려하면 Numpy의 'loadtxt'를 사용하여 생성기를 만드는 것이 유용할 수 있습니다.

data_array = NP.loadtxt(data_file.txt, delimiter=",")
def fnx() :
  for i in range(0, data_array.shape[1]) :
    yield dx[:,i]

펜윅 나무와 함께 비닝 (매우 큰 데이터 세트; 백분위 수 경계가 필요합니다)

이 접근법은 매우 다르고 다른 문제를 해결하기 때문에 같은 질문에 대한 두 번째 답변을 게시하고 있습니다.

매우 큰 데이터 세트 (수십억 샘플)가 있고 빈 경계가 어디에 있어야하는지 미리 알지 못하는 경우 어떻게해야합니까? 예를 들어, 당신은 사 분위수 나 사 분위수로 물건을 넣고 싶을 것입니다.

소형 데이터 세트의 경우 답변이 쉽습니다. 데이터를 배열에로드 한 다음 정렬 한 다음 배열을 통한 방식의 백분율로 점프하여 주어진 백분위 수에서 값을 읽습니다.

배열을 고정하는 메모리 크기가 실용적이지 않은 대형 데이터 세트의 경우 (정렬 할 시간은 말할 것도없이) ... "바이너리 인덱스 트리"인 Fenwick 트리를 사용하는 것을 고려하십시오.

나는 이것들이 긍정적 인 정수 데이터에만 효과가 있다고 생각하므로 Fenwick 트리에서 데이터를 테이핑하기 전에 데이터를 전환 (및 스케일) 할 수있는 데이터 세트에 대해 충분히 알아야합니다.

나는 이것을 사용하여 합리적인 시간과 매우 편안한 메모리 한계로 1000 억 샘플 데이터 세트의 중앙값을 찾았습니다. (다른 답변에 따라 생성기를 사용하여 파일을 열고 읽는 것을 고려하십시오. 여전히 유용합니다.)

Fenwick 나무에 대한 자세한 내용 :

발전기와 비닝 (큰 데이터 세트; 고정 된 width 빈; 플로트 데이터)

수백 또는 수천 개의 버킷이 있더라도 원하는 쓰레기통의 너비를 미리 알고 있다면 자신의 솔루션을 굴리는 것이 빠르고 (글쓰기, 실행) 빠르게 생각합니다. 다음은 파일에서 다음 값을 제공하는 반복기가 있다고 가정하는 파이썬입니다.

from math import floor
binwidth = 20
counts = dict()
filename = "mydata.csv"
for val in next_value_from_file(filename):
   binname = int(floor(val/binwidth)*binwidth)
   if binname not in counts:
      counts[binname] = 0
   counts[binname] += 1
print counts

값은 플로트 일 수 있지만 정수 binwidth를 사용한다고 가정합니다. 플로트 값의 쌍둥이를 사용하려면 이것을 조금 조정해야 할 수도 있습니다.

에 관해서 next_value_from_file(), 앞에서 언급했듯이 아마도 사용자 정의 생성기 또는 객체를 반복() 방법은 이것을 효율적으로 수행합니다. 그러한 생성기에 대한 의사 코드는 다음과 같습니다.

def next_value_from_file(filename):
  f = open(filename)
  for line in f:
     # parse out from the line the value or values you need
     val = parse_the_value_from_the_line(line)
     yield val

주어진 선에 여러 값이 있으면 parse_the_value_from_the_line() 목록을 반환하거나 자체를 생성기로 반환 하고이 의사 코드를 사용하십시오.

def next_value_from_file(filename):
  f = open(filename)
  for line in f:
     for val in parse_the_values_from_the_line(line):
       yield val
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top