[Python] 큰 CSV 파일에서 작은 무작위 표본을 파이썬 데이터 프레임으로 읽어들입니다.



Answers

다음은 파일의 행 수를 미리 계산하지 않아도되기 때문에 파일을 한 번만 읽으면됩니다.

m 개의 샘플을 원한다고합시다. 첫째, 알고리즘은 첫 번째 m 샘플을 유지합니다. 확률 m / i로 i 번째 샘플 (i> m)을 볼 때 알고리즘은 샘플을 사용하여 이미 선택된 샘플을 무작위로 바꿉니다.

이렇게함으로써, 어떤 i> m에 대해서도, 우리는 항상 첫 번째 샘플로부터 무작위로 선택된 m 개의 샘플의 부분 집합을 가진다.

아래 코드를 참조하십시오.

import random

n_samples = 10
samples = []

for i, line in enumerate(f):
    if i < n_samples:
        samples.append(line)
    elif random.random() < n_samples * 1. / (i+1):
            samples[random.randint(0, n_samples-1)] = line
Question

읽으려는 CSV 파일이 주 메모리에 맞지 않습니다. 몇 개의 (~ 10K) 무작위 라인을 읽고 선택한 데이터 프레임에 대한 간단한 통계를 작성하려면 어떻게해야합니까?




@ dlm의 answer 은 훌륭하지만 v0.20.0부터 skiprows 는 호출 가능을 허용합니다 . 호출 가능 함수는 행 번호를 인수로 수신합니다.

원하는 줄 수를 지정할 수 있으면 줄 수보다 파일 크기를 가져올 필요가 없으며 한 번 파일을 한 번 읽어야합니다. 첫 번째 행에 헤더가 있다고 가정합니다.

import pandas as pd
import random
p = 0.01  # 1% of the lines
# keep the header, then take only 1% of lines
# if random from [0,1] interval is greater than 0.01 the row will be skipped
df = pd.read_csv(
         filename,
         header=0, 
         skiprows=lambda i: i>0 and random.random() > p
)

또는, n 번째 줄마다 취하고 싶다면 :

n = 100  # every 100th line = 1% of the lines
df = pd.read_csv(filename, header=0, skiprows=lambda i: i % n != 0)



subsample 사용

pip install subsample
subsample -n 1000 file.csv > file_1000_sample.csv



아니 팬더!

import random
from os import fstat
from sys import exit

f = open('/usr/share/dict/words')

# Number of lines to be read
lines_to_read = 100

# Minimum and maximum bytes that will be randomly skipped
min_bytes_to_skip = 10000
max_bytes_to_skip = 1000000

def is_EOF():
    return f.tell() >= fstat(f.fileno()).st_size

# To accumulate the read lines
sampled_lines = []

for n in xrange(lines_to_read):
    bytes_to_skip = random.randint(min_bytes_to_skip, max_bytes_to_skip)
    f.seek(bytes_to_skip, 1)
    # After skipping "bytes_to_skip" bytes, we can stop in the middle of a line
    # Skip current entire line
    f.readline()
    if not is_EOF():
        sampled_lines.append(f.readline())
    else:
        # Go to the begginig of the file ...
        f.seek(0, 0)
        # ... and skip lines again
        f.seek(bytes_to_skip, 1)
        # If it has reached the EOF again
        if is_EOF():
            print "You have skipped more lines than your file has"
            print "Reduce the values of:"
            print "   min_bytes_to_skip"
            print "   max_bytes_to_skip"
            exit(1)
        else:
            f.readline()
            sampled_lines.append(f.readline())

print sampled_lines

sampled_lines 목록으로 끝납니다. 어떤 종류의 통계입니까?




Links