2016-11-11 64 views
7

Tôi vừa phát hiện ra sức mạnh của gấu trúc và tôi yêu nó, nhưng tôi không thể tìm ra vấn đề này:Nhóm Pandas DataFrame bởi n ngày bắt đầu từ sự khởi đầu của ngày

Tôi có một DataFrame 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 

tôi muốn nhóm dữ liệu của tôi thành chín khoảng ngày

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

nhóm thứ nhất:

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 
... 

nhóm Next:

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 
... 

Vì vậy, các dữ liệu được nhóm lại trong chín ngày, kể từ lần đầu tiên (12: 59: 31,717467), chứ không phải từ đầu những ngày như tôi muốn.

Khi nhóm của một ngày:

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

mang lại cho tôi:

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 
... 

tôi có thể chỉ vòng qua ngày cho đến khi tôi nhận được một khoảng thời gian chín ngày, nhưng tôi nghĩ rằng nó có thể được thực hiện thông minh hơn , Tôi đang tìm kiếm một lựa chọn cá mú freq tương đương với YS (đầu năm) chỉ trong vài ngày, một cách để thiết lập thời gian bắt đầu (có thể bởi tùy chọn Cá mú convention : {‘start’, ‘end’, ‘e’, ‘s’}), hoặc ???

Tôi đang chạy Python 3.5.2 và Pandas là trong phiên bản: 0.19.0

+0

[Câu trả lời] (http://stackoverflow.com/a/22528074/754456) đề xuất thêm tham số 'closed = 'left'' có thể làm điều đó? – mfitzp

+0

Tôi đã thử nó, nhưng không thay đổi một điều – user1643523

+0

Liệu 'convention = 's'' làm bất cứ điều gì? Tài liệu này thiếu nghiêm trọng về những tham số của 'TimeGrouper'. – mfitzp

Trả lời

1

Rớt lần đầu tiên hàng:

Đặt cược của bạn tốt nhất là nên normalize hàng đầu tiên của cột datetime để thời gian được thiết lập lại để 00:00:00 (nửa đêm) và nhóm theo khoảng 9D:

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 
# ...................................................................... 

Điều này khôi phục thời gian ở các hàng khác và vì vậy bạn sẽ không mất thông tin đó.


Giữ đầu hàng thời gian:

Nếu bạn muốn giữ hàng lần đầu tiên vì nó là và không thực hiện bất kỳ thay đổi nó, nhưng chỉ muốn bắt đầu nhóm từ nửa đêm trở đi, bạn có thể làm:

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

Cảm ơn câu trả lời – user1643523

1

Nếu bạn cắt datetimes đến nửa đêm của ngày nào đó, các nhóm sẽ làm việc như mong đợi (bắt đầu vào đầu ngày). Tôi hy vọng nó hoạt động bằng cách chuyển đổi để datetimes, ví dụ

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

Tuy nhiên, bạn không thể sử dụng TimeGrouper trừ khi chỉ số là một datetime. Bạn thay vì có hai lựa chọn, hoặc là cắt ngắn datetimes đến nửa đêm trực tiếp như sau:

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

Ngoài ra, trước tiên bạn có thể tạo ra date giá trị, sau đó chuyển đổi chúng trở lại datetimes, sử dụng pd.to_datetime() chức năng:

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

Cảm ơn câu trả lời – user1643523

1

hoàn @mfitzp trả lời bạn có thể làm điều này:

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

chỉ vấn đề với điều đó được df['dateonly'] sẽ không là một DatetimeIndex

bạn cần phải chuyển đổi nó lần đầu tiên:

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

bây giờ bạn có thể nhóm vào nó

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

và cung cấp thông tin thêm convention được sử dụng với PeriodIndex không DatetimeIndex

+0

Cảm ơn câu trả lời – user1643523

Các vấn đề liên quan