2016-08-01 11 views
3

numpyまたはpandasを使用して、CSVファイルの最後のN行をPythonで素早く読む方法はありますか?CSVファイルの最後のN行をnumpy/pandasで読む

  1. ファイルの長さが変化する、と私は常に最後のN行を必要とするので、私はnumpyまたはpandasskiprowskip_headerを行うことはできません。

  2. 私は純粋なPythonを使ってファイルの最後の行から1行ずつ読むことができますが、それは非常に遅いでしょう。もし私がする必要があれば、より効果的な方法をnumpyまたはpandas(これは本質的にCを使用しています)は本当に感謝します。

答えて

7

小さな10ラインのテストファイルで、私は2つのアプローチを試してみました - 全体を解析し、最後のN行を選択し、対すべての行を読み込むが、唯一の解析最後のNは:

In [1025]: timeit np.genfromtxt('stack38704949.txt',delimiter=',')[-5:] 
1000 loops, best of 3: 741 µs per loop 

In [1026]: %%timeit 
     ...: with open('stack38704949.txt','rb') as f: 
     ...:  lines = f.readlines() 
     ...: np.genfromtxt(lines[-5:],delimiter=',') 

1000 loops, best of 3: 378 µs per loop 

これはEfficiently Read last 'n' rows of CSV into DataFrameの複製としてタグ付けされました。ここで受け入れられた答えは、

from collections import deque 

を使用し、その構造の最後のN行を収集しました。また、不要な合併症であるため、パーサに行を供給するためにStringIOを使用しました。 genfromtxtは、それに行を与えるものから何かを入力するので、行のリストはうまくいきます。

In [1031]: %%timeit 
     ...: with open('stack38704949.txt','rb') as f: 
     ...:  lines = deque(f,5) 
     ...: np.genfromtxt(lines,delimiter=',') 

1000 loops, best of 3: 382 µs per loop 

readlinesとスライスと基本的に同じ時刻です。

dequeは、ファイルが非常に大きい場合に利点があり、すべての行にハングアップするコストがかかります。私はそれがファイルの読み込み時間を節約するとは思わない。まだ線を1つずつ読む必要があります。

row_countのタイミングに続いてskip_headerのタイミングが遅くなります。ファイルを2回読み取る必要があります。 skip_headerはまだ行を読み取る必要があります。カウントラインの目的のために

In [1046]: %%timeit 
     ...: with open('stack38704949.txt',"r") as f: 
     ...:  ...:  reader = csv.reader(f,delimiter = ",") 
     ...:  ...:  data = list(reader) 
     ...:  ...:  row_count = len(data) 
     ...: np.genfromtxt('stack38704949.txt',skip_header=row_count-5,delimiter=',') 

The slowest run took 5.96 times longer than the fastest. This could mean that an intermediate result is being cached. 
1000 loops, best of 3: 760 µs per loop 

多くの余分な時間を要するように見えませんが、我々は、csv.readerを使用する必要はありません。

In [1048]: %%timeit 
     ...: with open('stack38704949.txt',"r") as f: 
     ...: lines=f.readlines() 
     ...: row_count = len(data) 
     ...: np.genfromtxt('stack38704949.txt',skip_header=row_count-5,delimiter=',') 

1000 loops, best of 3: 736 µs per loop 
3

オプション1

あなたは、numpy.genfromtxtでファイル全体を読んでnumpyの配列として取得し、最後のN行を取ることができます:

a = np.genfromtxt('filename', delimiter=',') 
lastN = a[-N:] 

オプション2

普通のファイルの読書でも同様のことができます:

with open('filename') as f: 
    lastN = list(f)[-N:] 

今回は、最後のN行のリストを文字列として取得します。

lines = [] 
N = 10 
with open('csv01.txt') as f: 
    for line in f: 
     lines.append(line) 
     if len(lines) > 10: 
      lines.pop(0) 

が本当のCSVが必要です: -

オプション3メモリにファイル全体を読まなくては

は、我々は最後のN行各反復を保持するために、ほとんどのN項目のリストを使用しますマイナーチェンジ:skiprowsパラメータpandasread_csv()

import csv 
... 
with ... 
    for line in csv.reader(f): 
    ... 
2

使用、TOU gherの部分がcsvの行数を見つけています。ここで可能なソリューションです:

with open('filename',"r") as f: 
    reader = csv.reader(f,delimiter = ",") 
    data = list(reader) 
    row_count = len(data) 

df = pd.read_csv('filename', skiprows = row_count - N) 
関連する問題