2016-11-11 2 views
2

Я читал супер большой файл csv (10G), используя pandas, и read_csv (filename, chunksize = chunksize) возвращает мне итератор (предположим, что он называет «читатель»). И теперь я хочу получить точный фрагмент, потому что мне просто нужно несколько строк (например, файл csv, который я читаю, имеет 1000000000 строк, и я хочу получить номер 50000000 строк и 1000 строк после него), что мне делать кроме перебора итератора, пока он не достигнет куска, который я хочу?Как получить точный итератор python?

Вот мой бывший код:

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

не может просто сделать 'ДФ = pd.read_csv (имя_файла, SkipRows = 50000000, Nrows = 1000)'? – EdChum

+0

oh ... кажется, работает, я новичок в pandas .. – flyingrose

+0

Название * «Как получить точный номер итератора python?» «Не имеет для меня никакого смысла. Можете ли вы изменить его? – smci

ответ

0

Если вам нужно читать ваш CSV файл с разным размером кусков вы можете использовать iterator=True:

Предполагая, что мы имеем 1000rows DF (см в разделе настройки за то, как он был сформирован)

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 

ПРИМЕЧАНИЯ: get_chunk не может пропустить данные, он будет непрерывно считывать данные с указанным фрагментом размером

, если вы хотите прочитать только строки 100 - 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 

Но если вы можете использовать формат hdf5 - это будет гораздо проще и быстрее:

давайте сохраним его как hdf5 первый:

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

теперь мы можем прочитать его индексных позиций следующим образом:

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 

или запрашивая (SQL как):

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 

Установка:

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

спасибо, и, кстати, вы знаете, как работает pandas.read_csv (skiprows = skiprows)? Использует ли он двигатель C? – flyingrose

+0

@flyingrose, да, он должен использовать двигатель C, если только он не дает вам предупреждение о том, что двигатель C нельзя использовать из-за «» ... – MaxU

+0

, но как это работает? каким образом он просто игнорирует первые несколько строк? чтение куском? – flyingrose

Смежные вопросы