Bir DataFrame'i (yarı) düzensiz dönemlerle yeniden örneklemek için bir 'yemek kitabı' yolu var mı?Özel dönemlerle yeniden örnekleme
Günlük aralıklarla veri kümem var ve bazen (bilimsel literatürde) dekad'ın isminin ne olduğunu yeniden örneklendirmesini istiyorum. Bunun için uygun bir ingilizce terim olduğunu düşünmüyorum, ancak üçüncüsünün on üç gün içinde bir ayını kesiyor ve üçüncüsü 8 ile 11 gün arasında kalan bir şey.
Kendim için iki çözüm buldum, bu dava için belirli bir tane ve herhangi bir düzensiz dönem için daha genel bir tane. Ama her ikisi de çok iyi, bu yüzden başkalarının bu tür durumlarla nasıl başa çıktıklarını anlamak istiyorum.
bazı örnek verileri oluşturmaya başlayalım:
import pandas as pd
begin = pd.datetime(2013,1,1)
end = pd.datetime(2013,2,20)
dtrange = pd.date_range(begin, end)
p1 = np.random.rand(len(dtrange)) + 5
p2 = np.random.rand(len(dtrange)) + 10
df = pd.DataFrame({'p1': p1, 'p2': p2}, index=dtrange)
i elle dilimleme sonra bireysel ay (YYYYAA) göre gruplama ve ile gelen ilk şey. Gibi:
def to_dec1(data, func):
# create the indexes, start of the ~10day period
idx1 = pd.datetime(data.index[0].year, data.index[0].month, 1)
idx2 = idx1 + datetime.timedelta(days=10)
idx3 = idx2 + datetime.timedelta(days=10)
# slice the period and perform function
oneday = datetime.timedelta(days=1)
fir = func(data.ix[:idx2 - oneday].values, axis=0)
sec = func(data.ix[idx2:idx3 - oneday].values, axis=0)
thi = func(data.ix[idx3:].values, axis=0)
return pd.DataFrame([fir,sec,thi], index=[idx1,idx2,idx3], columns=data.columns)
dfmean = df.groupby(lambda x: x.strftime('%Y%m'), group_keys=False).apply(to_dec1, np.mean)
sonuçlanır
: Gerekirse
print dfmean
p1 p2
2013-01-01 5.436778 10.409845
2013-01-11 5.534509 10.482231
2013-01-21 5.449058 10.454777
2013-02-01 5.685700 10.422697
2013-02-11 5.578137 10.532180
2013-02-21 NaN NaN
her zaman karşılığında 'dekads' tam bir ay olsun Not, onun değil bir sorun ve kolay çıkarmak için.
Diğer çözüm, DataFrame'i kestiğiniz ve her segmentte bir işlev gerçekleştirebileceğiniz bir tarih aralığı sağlayarak çalışır. İstediğiniz dönemler bakımından daha esnek.
def to_dec2(data, dts, func):
chucks = []
for n,start in enumerate(dts[:-1]):
end = dts[n+1] - datetime.timedelta(days=1)
chucks.append(func(data.ix[start:end].values, axis=0))
return pd.DataFrame(chucks, index=dts[:-1], columns=data.columns)
dfmean2 = to_dec2(df, dfmean.index, np.mean)
Bir önceki zamanın indeksini, bir süre 'oluşturmak' için zaman aralığı olarak kullanıyorum.
Bu vakaları ele almanın en iyi yolu ne olurdu? Pandalarda belki de biraz daha inşa yöntemi var mı?
d = df.index.day - np.clip((df.index.day-1) // 10, 0, 2)*10 - 1
date = df.index.values - np.array(d, dtype="timedelta64[D]")
df.groupby(date).mean()
:
import pandas as pd
import numpy as np
begin = pd.datetime(2013,1,1)
end = pd.datetime(2013,2,20)
dtrange = pd.date_range(begin, end)
p1 = np.random.rand(len(dtrange)) + 5
p2 = np.random.rand(len(dtrange)) + 10
df = pd.DataFrame({'p1': p1, 'p2': p2}, index=dtrange)
dekad tarihini hesaplamak:
örnek verileri oluşturmak: Eğer numpy 1.7 kullanıyorsanız
yukarıda, daha sonra, (senin onları istediğiniz yerde rutin kolayca bu grupları doldurmak olabilir), [tarih, NUM_OF_DAYS] bir çok endeksi GroupBy olabilir normal gibi GroupBy. Her durumda TimeGrouper ile bunu yapmak için daha verimli bir yol var (ama bunu düşünmek zorundayım) – Jeff