2016-07-06 8 views
1

私は、大きなcsvファイルから0.18.1 pandasと2.7.10 PythonをWindows(8 Gb RAM)で使用してランダムな行を読み込む問題に直面しました。 。私はアプローチを見Read a small random sample from a big CSV file into a Python data frame大きなcsvファイル、python、pandasのランダムな行を読む

は、しかし、非常にメモリすなわち、消費し、コードの一部であることを私のPCのために発生しました:

n = 100 
s = 10 
skip = sorted(rnd.sample(xrange(1, n), n-s))# skip n-s random rows from *.csv  
data = pd.read_csv(path, usecols = ['Col1', 'Col2'], 
        dtype = {'Col1': 'int32', 'Col2':'int32'}, skiprows = skip) 

ので、私からいくつかのランダムな行を取りたい場合はファイルだけでなく、100行を考慮しますが、100 000、それはしかし、ファイルからランダムではない行を取って、硬くなり、ほぼ大丈夫です:

skiprows = xrange(100000)  
data = pd.read_csv(path, usecols = ['Col1', 'Col2'], 
        dtype = {'Col1': 'int32', 'Col2':'int32'}, skiprows = skip, nrows = 10000) 

Iからランダムに大量の行を読んで対処できる方法そこで質問大きなCSVファイルwi私はcsvファイル全体を読むことができないので、それをチャンクしても、ランダムな行にはっきりと興味があります。 おかげ

+1

私はこの質問に関する議論のほとんどが関連していると思います。要するに、メモリを大量に消費しない大きな解決策はありませんでした。 http://ipackoverflow.com/questions/38039723/splitting-a-large-pandas-dataframe-with-minimal-memory-footprint/38086123#38086123 – Jeff

+1

skiprowsはたくさんのメモリを使用し、チャンクを使って試してみます:http:// stackoverflow.com/questions/36874993/pandas-memory-error-after-a-certain-skiprows-parameter – ayhan

+0

これらのリンクのいずれかに行き、有用である場合は、可能であればそれらをupvoteしてください。 upvoteには15の評判が必要です。あなたは今6を持っています。 – piRSquared

答えて

0

私はこれが他の方法より速いと思っています。

リストでスキップする行をすでに選択しているとします。skippedまず、ルックアップブールテーブルに変換します。

# Some preparation: 
skipped = np.asarray(skipped) 
# MAX >= number of rows in the file 
bool_skipped = np.zeros(shape(MAX,), dtype=bool) 
bool_skipped[skipped] = True 

主なものは次のとおり

from io import StringIO 
# in Python 2 use 
# from StringIO import StringIO 

def load_with_buffer(filename, bool_skipped, **kwargs): 
    s_buf = StringIO() 
    with open(filename) as file: 
     count = -1 
     for line in file: 
      count += 1 
      if bool_skipped[count]: 
       continue 
      s_buf.write(line) 
    s_buf.seek(0) 
    df = pd.read_csv(s_buf, **kwargs) 
    return df 

私はそれをテストした:

df = pd.DataFrame(np.random.rand(100000, 100)) 
df.to_csv('test.csv') 

df1 = load_with_buffer('test.csv', bool_skipped, index_col=0) 

をスキップした行の90%に。

pd.read_csv('test.csv', skiprows=skipped, index_col=0) 

と同等に実行され、daskを使用するか、チャンクで読み取るよりも約3〜4倍高速です。

0

メモリが最大の問題である場合は、可能な解決策はチャンクを使用することで、ランダムチャンクから

n = 100 
s = 10 
factor = 1 # should be integer 
chunksize = int(s/factor) 

reader = pd.read_csv(path, usecols = ['Col1', 'Col2'],dtype = {'Col1': 'int32', 'Col2':'int32'}, chunksize=chunksize) 

out = [] 
tot = 0 
for df in reader: 
    nsample = random.randint(factor,chunksize) 
    tot += nsample 
    if tot > s: 
     nsample = s - (tot - nsample) 
    out.append(df.sample(nsample)) 
    if tot >= s: 
     break 

data = pd.concat(out) 

を選択し、チャンクの大きさを制御するための係数を使用することができます可能性があります。

+0

1つの問題は、各チャンクから選択を強制するので、このアプローチが本当にランダムではないということです。たとえば、n個のアイテムのランダムな選択が最初のn個のアイテムであり、チャンク化されたアプローチではこの可能性が認められない可能性はありますが、それは可能です。しかし、このアプローチは、ランダムな選択を必要とするほとんどのケースにとって十分であると主張することもできます。 – root

+0

そうです。私は、各チャンクからのサンプルの数がランダムであることを考慮に入れて答えを編集しました。しかし、ファイルの終わりに達する前に必要なサンプル数を得るためには、チャンクごとに少なくとも「要因」サンプルを持つ必要があるという点で注意が必要です。実際にランダムにするには、ファイルを複数回ループする可能性を考慮する必要があります。 –

+0

ありがとうございます、確かに、私はそれがまた抜け道であると信じています:チャンクを無作為に選んでそれらからランダムに行を選択して、この操作を繰り返します。それはskiprowsオプションよりもメモリ要求が少なく見えます。 –

関連する問題