我會嘗試做這種方式:
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
謝謝你的回答非常@MaxU。我相信這對我在這個問題中給出的具體例子起作用。但是,在某些情況下,我必須在進行計算之前處理數據,並且我想知道是否可以避免每次在所有塊上進行迭代。特別是,如果你沒有['age']列,而你有['date_of_birth']列,你將如何修改代碼?再次感謝! – Vincent
謝謝@MaxU。我仍然不知道是否可以「選擇」某些塊,但是你的解決方案是好的,而且不需要這樣做。如果你碰巧知道,我想如何使用'TextFileReader'對象,因爲我顯然沒有得到它是什麼以及它是如何工作的。 – Vincent
@Vincent,請檢查最新答案 – MaxU