2016-03-14 112 views
5

在熊貓中,我只能使用pandas.io.parser.read_csv("file.csv", nrows=10000)獲取csv文件的前10000行。獲取csv文件的最後10000行

但是因爲我的csv文件很大,最後一行比第一行更重要,所以我想讀最後的10000行。然而,即使我知道文件的長度,這也不是那麼容易,因爲如果我跳過1000000行csv文件的前99行,使用pandas.io.parser.read_csv("file.csv", nrows=10000, skiprows=990000),則包含文件頭的第一行也會被跳過。 (header=0是在應用skiprows之後測量的,所以它也沒有幫助。)

如何從第0行中的標頭獲得csv文件的最後10000行,最好不知道行中文件的長度?

+0

你在Linux或OSX系統上嗎?如果是這樣,那麼使用'tail -n 10000 file> file2'可能是最簡單的... – Carpetsmoker

+0

打擊@Carpetsmoker的想法,如果你堅持使用'Python',你可以在'subprocess.call )':P – Mai

+0

@Carpetsmoker,但他也需要一個標題。它應該是'head -n 1 file> file2; tail -n 10000 file >> file2' –

回答

5

你可以先計算出您與文件大小:

size = sum(1 for l in open('file.csv')) 

然後用skiprowsrange:與方案中提到

df = pd.read_csv('file.csv', skiprows=range(1, size - 10000)) 

編輯

由於@ivan_pozdeev你需要通過兩次文件。我試圖用熊貓閱讀整個文件,然後使用tail方法,但該方法比建議的慢。

實施例數據幀:

pd.DataFrame(np.random.randn(1000000,3), columns=list('abc')).to_csv('file.csv') 

時序

def f1(): 
    size = sum(1 for l in open('file.csv')) 
    return pd.read_csv('file.csv', skiprows=range(1, size - 10000)) 

def f2(): 
    return pd.read_csv('file.csv').tail(10000) 

In [10]: %timeit f1() 
1 loop, best of 3: 1.8 s per loop 

In [11]: %timeit f2() 
1 loop, best of 3: 1.94 s per loop 
+0

注意:這遍歷整個文件兩次。不是我(很容易)看到更好的方式... –

+0

@ivan_pozdeev我認爲,'pd.read_csv('file.csv')。tail(10000)'它會更快,但從時間上來說它會慢一點。 –

+2

用'tail',我推測,你首先將數據讀入一個'DataFrame',然後分片。這不僅會變慢,而且會冒出內存不足的風險。 –

1

採取恰好最後N行是as per Anton Protopopov,先通過整個文件,計數行的唯一方法。

但對於下一步驟,取它們,優化可製成(其tail所做的):

  • 你去,保存線的偏移量在長度爲N的循環緩衝器然後,在結束時,緩衝區中最舊的項目將是所需的偏移量。然後,按照Working with 10+GB dataset in Python Pandas,文件對象上的所有內容爲f.seek()

不包括經歷的整個文件將不需要線的確切數目更快的方式:從我所看到的,你只需要任意大量。所以,你可以:

  • 得到偏移的粗略估計你需要尋求到(例如,計算/估計線的平均長度)
  • 尋求在那裏,然後到下一個(或以前的)換行符

    如果你的數據有嵌入換行符,這需要格外小心:在這種情況下,沒有防止檢測哪些引號打開和哪些引腳正在關閉的方法。你必須對什麼可以和什麼不能在內/外引號做出假設......甚至還有多遠尋找一個報價來確定是否嵌入換行符!

0

你可以嘗試從tail大熊貓,它返回最後n行

df.tail(10000) 
3

使用@Anton Protopopov樣本文件。在單獨的操作中讀取文件和標題的部分位數比讀取整個文件要便宜得多。

就直接讀取最終行

In [22]: df = read_csv("file.csv", nrows=10000, skiprows=990001, header=None, index_col=0) 

In [23]: df 
Out[23]: 
       1   2   3 
0         
990000 -0.902507 -0.274718 1.155361 
990001 -0.591442 -0.318853 -0.089092 
990002 -1.461444 -0.070372 0.946964 
990003 0.608169 -0.076891 0.431654 
990004 1.149982 0.661430 0.456155 
...   ...  ...  ... 
999995 0.057719 0.370591 0.081722 
999996 0.157751 -1.204664 1.150288 
999997 -2.174867 -0.578116 0.647010 
999998 -0.668920 1.059817 -2.091019 
999999 -0.263830 -1.195737 -0.571498 

[10000 rows x 3 columns] 

相當快做到這一點

In [24]: %timeit read_csv("file.csv", nrows=10000, skiprows=990001, header=None, index_col=0) 
1 loop, best of 3: 262 ms per loop 

相當便宜,以確定該文件的先驗

In [25]: %timeit sum(1 for l in open('file.csv')) 
10 loops, best of 3: 104 ms per loop 

閱讀中的長標題

In [26]: df.columns = read_csv('file.csv', header=0, nrows=1, index_col=0).columns 

In [27]: df 
Out[27]: 
       a   b   c 
0         
990000 -0.902507 -0.274718 1.155361 
990001 -0.591442 -0.318853 -0.089092 
990002 -1.461444 -0.070372 0.946964 
990003 0.608169 -0.076891 0.431654 
990004 1.149982 0.661430 0.456155 
...   ...  ...  ... 
999995 0.057719 0.370591 0.081722 
999996 0.157751 -1.204664 1.150288 
999997 -2.174867 -0.578116 0.647010 
999998 -0.668920 1.059817 -2.091019 
999999 -0.263830 -1.195737 -0.571498 

[10000 rows x 3 columns]