2016-11-11 66 views
7

我剛剛發現熊貓的動力,我喜歡它,但我無法弄清楚這個問題:分組熊貓數據幀由n天開始當天的開頭

我有一個數據幀df.head()

lon lat h filename     time 
0 19.961216 80.617627 -0.077165  60048 2002-05-15 12:59:31.717467 
1 19.923916 80.614847 -0.018689  60048 2002-05-15 12:59:31.831467 
2 19.849396 80.609257 -0.089205  60048 2002-05-15 12:59:32.059467 
3 19.830776 80.607857  0.076485  60048 2002-05-15 12:59:32.116467 
4 19.570708 80.588183  0.162943  60048 2002-05-15 12:59:32.888467 

我想我的組數據爲九個天的間隔

gb = df.groupby(pd.TimeGrouper(key='time', freq='9D')) 

第一組:

2002-05-15 12:59:31.717467  lon lat h filename     time 
0 19.961216 80.617627 -0.077165  60048 2002-05-15 12:59:31.717467 
1 19.923916 80.614847 -0.018689  60048 2002-05-15 12:59:31.831467 
2 19.849396 80.609257 -0.089205  60048 2002-05-15 12:59:32.059467 
3 19.830776 80.607857  0.076485  60048 2002-05-15 12:59:32.116467 
... 

下一組:(:59:31.717467 12)從一天的開始,而不是因爲我想

2002-05-24 12:59:31.717467  lon lat height filename     time 
815 18.309498 80.457024  0.187387  60309 2002-05-24 16:35:39.553563 
816 18.291458 80.458514  0.061446  60309 2002-05-24 16:35:39.610563 
817 18.273408 80.460014  0.129255  60309 2002-05-24 16:35:39.667563 
818 18.255358 80.461504  0.046761  60309 2002-05-24 16:35:39.724563 
... 

所以數據九天從第一計時分組。

當以一天分組:

gb = df.groupby(pd.TimeGrouper(key='time', freq='D')) 

給我:

2002-05-15 00:00:00  lon lat h filename     time 
0 19.961216 80.617627 -0.077165  60048 2002-05-15 12:59:31.717467 
1 19.923916 80.614847 -0.018689  60048 2002-05-15 12:59:31.831467 
2 19.849396 80.609257 -0.089205  60048 2002-05-15 12:59:32.059467 
3 19.830776 80.607857  0.076485  60048 2002-05-15 12:59:32.116467 
... 

我就可以在幾天循環,直到我得到一個九天的間隔,但我認爲它可以做更聰明,我正在尋找相當於YS(年初)的Grouper freq選項,只需幾天,設置開始時間的一種方法(可能通過Grouper選項convention : {‘start’, ‘end’, ‘e’, ‘s’}),或者?

我運行的Python 3.5.2和熊貓是在版本:0.19.0

+0

[這個答案](http://stackoverflow.com/a/22528074/754456)建議添加參數'閉合='left''可能做到這一點? – mfitzp

+0

我試過了,但沒有改變什麼 – user1643523

+0

'convention ='s''做了什麼嗎?文檔嚴重缺乏'TimeGrouper'的參數。 – mfitzp

回答

1

第一次滴行:

最好的辦法將是normalizedatetime列的第一行根據9D間隔,使得時間被重置00:00:00(午夜)和組:

df.loc[0, 'time'] = df['time'].iloc[0].normalize() 
for _, grp in df.groupby(pd.TimeGrouper(key='time', freq='9D')): 
    print (grp) 

#   lon  lat   h filename      time 
# 0 19.961216 80.617627 -0.077165  60048 2002-05-15 00:00:00.000000 
# 1 19.923916 80.614847 -0.018689  60048 2002-05-15 12:59:31.831467 
# 2 19.849396 80.609257 -0.089205  60048 2002-05-15 12:59:32.059467 
# 3 19.830776 80.607857 0.076485  60048 2002-05-15 12:59:32.116467 
# 4 19.570708 80.588183 0.162943  60048 2002-05-15 12:59:32.888467 
# ...................................................................... 

這會在其他行中恢復時間,因此您不會丟失該信息。


保持第一次行:

如果你想保持在第一時間行,因爲它是不作任何修改,但只是想開始從午夜分組起,你可以這樣做:

df_t_shift = df.shift() # Shift one level down 
df_t_shift.loc[0, 'time'] = df_t_shift['time'].iloc[1].normalize() 
# Concat last row of df with the shifted one to account for the loss of row 
df_t_shift = df_t_shift.append(df.iloc[-1], ignore_index=True) 

for _, grp in df_t_shift.groupby(pd.TimeGrouper(key='time', freq='9D')): 
    print (grp) 

#   lon  lat   h filename      time 
# 0  NaN  NaN  NaN  NaN 2002-05-15 00:00:00.000000 
# 1 19.961216 80.617627 -0.077165 60048.0 2002-05-15 12:59:31.717467 
# 2 19.923916 80.614847 -0.018689 60048.0 2002-05-15 12:59:31.831467 
# 3 19.849396 80.609257 -0.089205 60048.0 2002-05-15 12:59:32.059467 
# 4 19.830776 80.607857 0.076485 60048.0 2002-05-15 12:59:32.116467 
# 5 19.570708 80.588183 0.162943 60048.0 2002-05-15 12:59:32.888467 
+1

感謝您的回答 – user1643523

1

如果截斷日期時間給定的一天午夜,如預期的分組就可以了(開始在一天的開始)。我預期通過轉換爲日期時間的工作,e.g

df['date'] = df['time'].apply(lambda x:x.date()) 

但是,您不能使用TimeGrouper除非索引是一個datetime。 你不是有兩個選擇,要麼直接截斷日期時間至午夜如下:

df['date'] = df['time'].apply(lambda x:x.replace(hour=0, minute=0, second=0, microsecond=0))) 

或者,您可以先產生date值,然後將其轉換回日期時間,使用pd.to_datetime()功能:

df['date'] = df['time'].apply(lambda x: x.date()) 
df['date'] = pd.to_datetime(df['date']) 
+0

感謝您的回答 – user1643523

1

完成@mfitzp回答你可以這樣做:

df['dateonly'] = df['time'].apply(lambda x: x.date()) 

只與問題是df['dateonly']不會是一個DatetimeIndex

你需要先將其轉換:

df['dateonly'] = pd.to_datetime(df['dateonly']) 

現在你可以在它

gb = df.groupby(pd.TimeGrouper(key='dateonly', freq='9D')) 

和額外的信息convention組用於與PeriodIndexDatetimeIndex

+0

感謝您的回答 – user1643523