2016-11-11 2 views
2

Ich las eine super große CSV-Datei (10G) mit Pandas, und read_csv (Dateiname, Chunksize = Chunksize) gib mir einen Iterator (Assum nennt es "Leser"). Und jetzt möchte ich einen genauen Chunk bekommen, weil ich nur ein paar Zeilen möchte (zum Beispiel hat die CSV-Datei, die ich gelesen habe, 1000000000 Zeilen, und ich möchte 50000000 Zeilen und 1000 Zeilen danach bekommen), was soll ich tun außer den Iterator zu tranversieren, bis er den gewünschten Chunk erreicht?Wie bekomme ich einen genauen Python-Iterator?

Hier ist mein ehemaliger Code:

def get_lines_by_chunk(file_name, line_beg, line_end, chunk_size=-1): 
func_name = 'get_lines_by_chunk' 
line_no = get_file_line_no(file_name) 

if chunk_size < 0: 
    chunk_size = get_chunk_size(line_no, line_beg, line_end) 

reader = pd.read_csv(file_name, chunksize=chunk_size) 
data = pd.DataFrame({}) 

flag = 0 

for chunk in reader: 
    line_before = flag * chunk_size 
    flag = flag + 1 
    line_after = flag * chunk_size 
    if line_beg >= line_before and line_beg <= line_after: 
     if line_end >= line_after: 
      temp = chunk[line_beg - line_before : chunk_size] 
      data = pd.concat([data, temp], ignore_index=True) 
     else: 
      temp = chunk[line_beg - line_before : line_end - line_before] 
      data = pd.concat([data, temp], ignore_index=True) 
      return data 
    elif line_end <= line_after and line_end >= line_before: 
     temp = chunk[0 : line_end - line_before] 
     data = pd.concat([data, temp], ignore_index=True) 
     return data 
    elif line_beg < line_before and line_end > line_after: 
     temp = chunk[0 : chunk_size] 
     data = pd.concat([data, temp], ignore_index=True) 

return data 
+1

kann nicht einfach tun 'df = pd.read_csv (file_name, skiprows = 50000000, nrows = 1000)'? – EdChum

+0

oh ... es scheint funktioniert, ich bin neu in pandas .. – flyingrose

+0

Der Titel * "Wie bekomme ich einen genauen Python Iterator? *" Macht keinen Sinn für mich. Kannst du es umschreiben? – smci

Antwort

0

Wenn Sie Ihre CSV-Datei mit unterschiedlich großen Brocken lesen können Sie verwenden iterator=True:

wir haben einen 1000rows DF Unter der Annahme (im Setup finden Sie im Abschnitt für, wie es erzeugt wurde)

In [103]: reader = pd.read_csv(fn, iterator=True) 

In [104]: reader.get_chunk(5) 
Out[104]: 
    a b 
0 1 8 
1 2 28 
2 3 85 
3 4 56 
4 5 29 

In [105]: reader.get_chunk(3) 
Out[105]: 
    a b 
5 6 55 
6 7 16 
7 8 96 

HINWEIS: get_chunk Daten nicht überspringen kann, wird es kontinuierlich Daten mit dem angegebenen Chunk liest Größen

, wenn Sie nur die Zeilen 100 lesen - 110:

In [106]: cols = pd.read_csv(fn, nrows=1).columns.tolist() 

In [107]: cols 
Out[107]: ['a', 'b'] 

In [109]: pd.read_csv(fn, header=None, skiprows=100, nrows=10, names=cols) 
Out[109]: 
    a b 
0 100 52 
1 101 15 
2 102 74 
3 103 10 
4 104 35 
5 105 73 
6 106 48 
7 107 49 
8 108 1 
9 109 56 

Aber wenn Sie HDF5 Format verwenden können - es wird viel einfacher und schneller:

machen wir es als HDF5 zuerst speichern:

In [110]: df.to_hdf('c:/temp/test.h5', 'mydf', format='t', data_columns=True, compression='blosc', complevel=9) 

jetzt können wir es von Indexpositionen wie folgt lauten:

In [113]: pd.read_hdf('c:/temp/test.h5', 'mydf', start=99, stop=109) 
Out[113]: 
     a b 
99 100 52 
100 101 15 
101 102 74 
102 103 10 
103 104 35 
104 105 73 
105 106 48 
106 107 49 
107 108 1 
108 109 56 

oder Abfragen (SQL wie):

In [115]: pd.read_hdf('c:/temp/test.h5', 'mydf', where="a >= 100 and a <= 110") 
Out[115]: 
     a b 
99 100 52 
100 101 15 
101 102 74 
102 103 10 
103 104 35 
104 105 73 
105 106 48 
106 107 49 
107 108 1 
108 109 56 
109 110 23 

Setup:

In [99]: df = pd.DataFrame({'a':np.arange(1, 1001), 'b':np.random.randint(0, 100, 1000)}) 

In [100]: fn = r'C:\Temp\test.csv' 

In [101]: df.to_csv(fn, index=False) 

In [102]: df.shape 
Out[102]: (1000, 2) 
+0

danke, und wissen Sie übrigens, wie pandas.read_csv (skiprows = skiprows) funktioniert? Verwendet es eine C-Engine? – flyingrose

+0

@flyingrose, ja, sollte es C-Motor verwenden, es sei denn es gibt Ihnen eine Warnung, dass C-Motor kann nicht wegen "" ... – MaxU

+0

verwendet werden, aber wie es funktioniert? Wie ignoriert es die ersten Zeilen? Lesen nach Stück? – flyingrose

Verwandte Themen