2017-05-29 19 views
1

我需要導入一個大的.txt文件(大約10GB)來做一些計算。我在Python 2.7中使用熊貓。Python&Pandas。如何在TextFileReader對象中使用「塊」的子集?

基本上,我需要根據其他系列的值構造特定系列(列)的總和和平均值。更確切地說:我掌握了居住在一個國家的個人的基本信息,例如,我想要考慮每個城市人們的平均年齡。

我無法導入整個文件(因爲它太大了),所以我(使用read_tablechunksize)做的「塊」。 對於每個計算,我不需要所有的塊,只是它們的一個子集。

由於信息可能無法排序,因此我首先遍歷所有區塊,以確定其中哪些區域具有每個城市的信息。因此,對於每個城市,我都有一個包含至少包含一個屬於它的觀察值的塊的索引列表。

然後,我想使用此列表來選擇只有那些塊,但我無法以快速的方式做到這一點。 似乎工作的唯一一件事是再次遍歷所有塊。

有沒有辦法直接選擇一個TextFileReader對象中的「塊」的子集,而無需遍歷所有這些「塊」?

回答

0

我會嘗試做這種方式:

res = \ 
pd.concat([df.assign(age=(pd.datetime.now() - df.dob).astype('m8[Y]').astype(int)) 
      .groupby(['country','municipality'])['age'].agg(['size','sum']).reset_index() 
      for df in pd.read_csv('/path/to/file.txt', sep=..., chunksize=10**5) ], 
      ignore_index=True) 

res = res.groupby(['country','municipality'], as_index=False).sum() 

這會給你個人的總數在每個市(size列)和他們的年齡的總和(sum列)。

sum/size - 會給你一個平均年齡每直轄市

UPDATE:您可以使用下面的技巧,以實時計算年齡:

In [164]: df 
Out[164]: 
    country municipality  dob 
0 Ukraine   m1 1950-01-01 
1 Ukraine   m1 1960-12-14 
2  USA   m2 1971-11-27 
3  USA   m2 1982-11-09 
4  USA   m3 1993-10-22 
5 Germany   m1 2004-10-04 
6 Germany   m2 2015-09-17 

In [165]: df.assign(age=(pd.datetime.now() - df.dob).astype('m8[Y]').astype(int)) 
Out[165]: 
    country municipality  dob age 
0 Ukraine   m1 1950-01-01 67 
1 Ukraine   m1 1960-12-14 56 
2  USA   m2 1971-11-27 45 
3  USA   m2 1982-11-09 34 
4  USA   m3 1993-10-22 23 
5 Germany   m1 2004-10-04 12 
6 Germany   m2 2015-09-17 1 

UPDATE2:pd.read_csv()只要您指定chunksize即可返回pandas.io.parsers.TextFileReader而不是DataFrame

In [6]: reader = pd.read_csv(r'D:\temp\.data\1.csv', chunksize=3, sep='\s+') 

In [7]: type(reader) 
Out[7]: pandas.io.parsers.TextFileReader 

得到2行

In [12]: reader.get_chunk(2) 
Out[12]: 
     foo foo.1 bar bar.1 spam spam.1 
foo 0.00 0.35 0.83 0.84 0.90 0.89 
foo 0.35 0.00 0.86 0.85 0.92 0.91 

獲得未來3行

In [13]: reader.get_chunk(3) 
Out[13]: 
     foo foo.1 bar bar.1 spam spam.1 
bar 0.83 0.86 0.00 0.25 0.88 0.87 
bar 0.84 0.85 0.25 0.00 0.82 0.86 
spam 0.90 0.92 0.88 0.82 0.00 0.50 
+0

謝謝你的回答非常@MaxU。我相信這對我在這個問題中給出的具體例子起作用。但是,在某些情況下,我必須在進行計算之前處理數據,並且我想知道是否可以避免每次在所有塊上進行迭代。特別是,如果你沒有['age']列,而你有['date_of_birth']列,你將如何修改代碼?再次感謝! – Vincent

+0

謝謝@MaxU。我仍然不知道是否可以「選擇」某些塊,但是你的解決方案是好的,而且不需要這樣做。如果你碰巧知道,我想如何使用'TextFileReader'對象,因爲我顯然沒有得到它是什麼以及它是如何工作的。 – Vincent

+0

@Vincent,請檢查最新答案 – MaxU

相關問題