import numpy as np
import pandas as pd
n = 10
nrows = 33
index = pd.date_range('2000-1-1', periods=nrows, freq='D')
df = pd.DataFrame(np.ones(nrows), index=index)
print(df)
# 0
# 2000-01-01 1
# 2000-01-02 1
# ...
# 2000-02-01 1
# 2000-02-02 1
first = df.index.min()
last = df.index.max() + pd.Timedelta('1D')
secs = int((last-first).total_seconds()//n)
periodsize = '{:d}S'.format(secs)
result = df.resample(periodsize, how='sum')
print('\n{}'.format(result))
assert len(result) == n
rentowności
0
2000-01-01 00:00:00 4
2000-01-04 07:12:00 3
2000-01-07 14:24:00 3
2000-01-10 21:36:00 4
2000-01-14 04:48:00 3
2000-01-17 12:00:00 3
2000-01-20 19:12:00 4
2000-01-24 02:24:00 3
2000-01-27 09:36:00 3
2000-01-30 16:48:00 3
wartości w 0
-kolumna wskazuje liczbę zagregowanych wierszy, ponieważ oryginalna ramka DataFrame została wypełniona wartościami 1. Wzorzec 4 i 3 jest mniej więcej taki, jaki można uzyskać, ponieważ 33 wiersze nie mogą być równo podzielone na 10 grup.
Wyjaśnienie: Rozważmy to prostsze DataFrame:
n = 2
nrows = 5
index = pd.date_range('2000-1-1', periods=nrows, freq='D')
df = pd.DataFrame(np.ones(nrows), index=index)
# 0
# 2000-01-01 1
# 2000-01-02 1
# 2000-01-03 1
# 2000-01-04 1
# 2000-01-05 1
Korzystanie df.resample('2D', how='sum')
daje złą liczbę grup
In [366]: df.resample('2D', how='sum')
Out[366]:
0
2000-01-01 2
2000-01-03 2
2000-01-05 1
Korzystanie df.resample('3D', how='sum')
daje prawo liczbę grup, ale druga grupa zaczyna się od 2000-01-04
, która nie ev enly podzielić DataFrame na dwie jednakowo rozmieszczonych grup:
In [367]: df.resample('3D', how='sum')
Out[367]:
0
2000-01-01 3
2000-01-04 2
Aby to zrobić lepiej, musimy pracować w lepszej rozdzielczości czasowej niż w dniach. Od Timedelta
s mają metodę total_seconds
, pracujmy w kilka sekund.Tak na powyższym przykładzie, żądany ciąg częstotliwość byłaby
In [374]: df.resample('216000S', how='sum')
Out[374]:
0
2000-01-01 00:00:00 3
2000-01-03 12:00:00 2
ponieważ istnieją 216000 * 2 sekundy w 5 dni:
In [373]: (pd.Timedelta(days=5)/pd.Timedelta('1S'))/2
Out[373]: 216000.0
Ok, więc teraz wszyscy musimy to sposób uogólnić to . Będziemy potrzebować minimalnych i maksymalnych dat w indeksie:
first = df.index.min()
last = df.index.max() + pd.Timedelta('1D')
Dodajemy dodatkowy dzień, ponieważ sprawia to, że różnica w dniach wychodzi dobrze. W powyższym przykładzie Są tylko 4 dni pomiędzy znaczniki czasu do 2000-01-05 i 2000-01-01,
In [377]: (pd.Timestamp('2000-01-05')-pd.Timestamp('2000-01-01')).days
Out[378]: 4
Ale jak widać w pracował przykład DataFrame ma 5 rzędów reprezentujących 5 dni. Ma więc sens dodanie dodatkowego dnia.
Teraz możemy obliczyć prawidłową liczbę sekund w każdym równo rozmieszczone z grupy:
secs = int((last-first).total_seconds()//n)
Wydaje się to dość proste. Doceniam również dodatkowe wyjaśnienie. Dzięki! –