2014-11-07 8 views
3

Все -Python панда DataFrame из первой и последней строки CSV

Ищу создать панда DataFrame только из первых и последних строк очень большого CSV. Целью этого упражнения является возможность легко захватить некоторые атрибуты из первой и последней записей в этих файлах csv. У меня нет никаких проблем, захватывая первую строку CSV, используя: не

pd.read_csv(filename, nrows=1) 

Я также не проблема захвата последней строки текстового файла различными способами, такими как:

with open(filename) as f: 
    last_line = f.readlines()[-1] 

Однако, получение эти две вещи в один DataFrame меня бросили на цикл. Любое понимание того, как наилучшим образом достичь этой цели?

EDIT ПРИМЕЧАНИЕ. Я пытаюсь выполнить эту задачу, не загружая все данные в один DataFrame, поскольку я имею дело с довольно большими (> 15MM строками) csv-файлами.

Спасибо!

+1

вы можете показать шаги, которые вы предприняли, пытаясь получить эти две вещи в одну DataFrame?и какая у вас ошибка – Anzel

+0

@ Anzel первый фрагмент успешно захватывает первую строку и помещает ее в DataFrame. Второй фрагмент захватывает последнюю строку, но в нем отсутствуют заголовки, поэтому я не могу создать новый DataFrame и использовать простое объединение для объединения. – wrcobb

ответ

5

Просто используйте head и tail и concat. Вы даже можете настроить количество строк.

import pandas as pd 

df = pd.read_csv("flu.csv") 
top = df.head(1) 
bottom = df.tail(1) 
concatenated = pd.concat([top,bottom]) 

print concatenated 

Результат:

  Date Cases 
0  9/1/2014  45 
121 12/31/2014  97 

Регулировка head и tail взять в 5 строк из верхней и 10 снизу ...

  Date Cases 
0  9/1/2014  45 
1  9/2/2014 104 
2  9/3/2014  47 
3  9/4/2014 108 
4  9/5/2014  49 
112 12/22/2014  30 
113 12/23/2014  81 
114 12/24/2014  99 
115 12/25/2014  85 
116 12/26/2014  55 
117 12/27/2014  91 
118 12/28/2014  68 
119 12/29/2014 109 
120 12/30/2014  55 
121 12/31/2014  97 

Один из возможных подходов, которые могут быть использованы если вы не хотите загружать весь CSV-файл в качестве фреймворка данных, это обрабатывать их как CSV. Следующий код похож на ваш подход.

import pandas as pd 
import csv 

top = pd.read_csv("flu.csv", nrows=1) 
headers = top.columns.values 

with open("flu.csv", "r") as f, open("flu2.csv","w") as g: 
    last_line = f.readlines()[-1].strip().split(",") 
    c = csv.writer(g) 
    c.writerow(headers) 
    c.writerow(last_line) 

bottom = pd.read_csv("flu2.csv") 
concatenated = pd.concat([top, bottom]) 
concatenated.reset_index(inplace=True, drop=True) 

print concatenated 

Результат такой же, за исключением указаний. Протестировано против миллиона строк, и обработано примерно через секунду.

 Date Cases 
0 9/1/2014  45 
1 7/25/4885  99 
[Finished in 0.9s] 

Как масштабируется по сравнению с 15 миллионами строк, может быть, ваша игра в мяч прямо сейчас. Так что я решил протестировать его ровно 15 728 626 строк, и результаты кажутся достаточно хорошими.

 Date Cases 
0 9/1/2014  45 
1 7/25/4885  99 
[Finished in 3.3s] 
+0

Спасибо за ваш ответ - все мысли о том, как это сделать, без первой загрузки всего файла в DataFrame? Я должен был быть более явным в своем посте, но это очень большие (15MM row plus) файлы csv, поэтому я стараюсь не загружать весь набор данных. Я также отредактирую свой вопрос. – wrcobb

+1

Является ли количество строк постоянными или это изменяется? – Manhattan

+0

Число строк не является постоянным. Я уже подсчитываю общее количество строк в анализируемом файле в другом месте моего сценария, поэтому у меня есть этот набор данных в моем распоряжении. – wrcobb

3

Таким образом, способ сделать это, не читая в весь файл в Python первым, чтобы захватить первую линию затем перебирать файл в последней строке. Затем используйте StringIO, чтобы сосать их в Pandas. Может быть, что-то вроде этого:

import pandas as pd 
import StringIO 

with open('tst.csv') as f: 
    first_line = f.readline() 
    for line in f: 
     pass #iterate to the end 
    last_line = line 

mydf = pd.DataFrame() 
mydf = mydf.append(pd.read_csv(StringIO.StringIO(first_line), header=None)) 
mydf = mydf.append(pd.read_csv(StringIO.StringIO(last_line), header=None)) 
2

Вы хотите этот ответ https://stackoverflow.com/a/18603065/4226476 - не принятый ответ, но лучше всего, потому что он стремится назад к первому символу новой строки, вместо того, чтобы гадать.

Затем заверните две строки в StringIO:

from cStringIO import StringIO 
import pandas as pd 

# grab the lines as per first-and-last-line question 
truncated_input = StringIO(the_two_lines) 
truncated_input.seek(0) # need to rewind 
df = pd.read_csv(truncated_input) 
+0

Думаю, вам понадобится заголовок = None на read_csv. В противном случае pandas будет обрабатывать строку как заголовок. –

+0

(... или взять первые две строки и последние ...) –

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