क्या डेटाफ्रेम को (अर्ध) अनियमित अवधि के साथ पुन: स्थापित करने का 'कुकबुक' तरीका है?कस्टम अवधि के साथ resampling
मेरे पास दैनिक अंतराल पर एक डेटासेट है और इसे कभी-कभी (वैज्ञानिक साहित्य में) डेकड नाम देने के लिए दोहराना चाहते हैं। मुझे नहीं लगता कि इसके लिए एक उचित अंग्रेजी शब्द है लेकिन यह मूल रूप से तीन महीने के दस भागों में एक महीने काट रहा है जहां तीसरा 8 और 11 दिनों के बीच कुछ भी शेष है।
मैं अपने आप के दो समाधानों के साथ आया, इस मामले के लिए एक विशिष्ट और किसी भी अनियमित अवधि के लिए एक सामान्य सामान्य। लेकिन दोनों वास्तव में अच्छे नहीं हैं, इसलिए मैं इस तरह की परिस्थितियों को कैसे संभालता हूं, इस बारे में शर्मिंदा हूं।
नमूना डेटा बनाने के साथ शुरू की सुविधा देता है:
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)
पहली बात मैं के साथ अलग-अलग महीनों (YYYYMM) द्वारा समूहीकरण जाता है और फिर इसे मैन्युअल रूप से टुकड़ा करने की क्रिया आया। जैसा:
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)
कौन सा में परिणाम:
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
ध्यान दें कि आप हमेशा बदले में 'dekads' की एक पूरी माह मिलता है, इसकी नहीं एक समस्या और आसान अगर जरूरत को हटाने के लिए।
दूसरा समाधान डेटाफ्रेम को काटने और प्रत्येक सेगमेंट पर फ़ंक्शन करने के लिए कई तिथियां प्रदान करके काम करता है। आप जो अवधि चाहते हैं उसके संदर्भ में यह अधिक लचीला है।
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)
ध्यान दें कि पिछले परिणाम की अनुक्रमणिका का उपयोग करके मैं कुछ समय 'बिल्डिंग' को बचाने के लिए तारीखों की सीमा के रूप में उपयोग कर रहा हूं।
इन मामलों को संभालने का सबसे अच्छा तरीका क्या होगा? क्या पांडों में शायद थोड़ी अधिक बिल्ड-इन विधि है?
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 की तारीख की गणना:
नमूना डेटा बनाने के लिए:
, आप, [तिथि, NUM_OF_DAYS] की एक बहु सूचकांक पर GroupBy (अपनी दिनचर्या आसानी से इन समूहों को पॉप्युलेट सकता है जहाँ भी अपने चाहते हैं उन्हें), तो सामान्य की तरह GroupBy सकता है। किसी भी घटना में टाइमग्राउपर के साथ ऐसा करने का शायद एक और अधिक प्रभावी तरीका है (लेकिन मुझे इसके बारे में सोचना है) – Jeff