2013-03-14 6 views
9

क्या डेटाफ्रेम को (अर्ध) अनियमित अवधि के साथ पुन: स्थापित करने का 'कुकबुक' तरीका है?कस्टम अवधि के साथ 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 की तारीख की गणना:

नमूना डेटा बनाने के लिए:

+0

, आप, [तिथि, NUM_OF_DAYS] की एक बहु सूचकांक पर GroupBy (अपनी दिनचर्या आसानी से इन समूहों को पॉप्युलेट सकता है जहाँ भी अपने चाहते हैं उन्हें), तो सामान्य की तरह GroupBy सकता है। किसी भी घटना में टाइमग्राउपर के साथ ऐसा करने का शायद एक और अधिक प्रभावी तरीका है (लेकिन मुझे इसके बारे में सोचना है) – Jeff

उत्तर

7

आप numpy 1.7 का उपयोग करते हैं, तो आप गणना करने के लिए datetime64 & timedelta64 सरणियों उपयोग कर सकते हैं आउटपुट है:

    p1   p2 
2013-01-01 5.413795 10.445640 
2013-01-11 5.516063 10.491339 
2013-01-21 5.539676 10.528745 
2013-02-01 5.783467 10.478001 
2013-02-11 5.358787 10.579149 
+0

धन्यवाद, एक आकर्षण की तरह काम करता है। –

2

d चर की गणना से HYRY के डेटा और समाधान अप का उपयोग करना, हम भी कर सकते हैं पांडा 0.11-देव या बाद में निम्नलिखित (चाहे numpy संस्करण):

In [18]: from datetime import timedelta 

In [23]: pd.Series([ timedelta(int(i)) for i in d ]) 
Out[23]: 
0    00:00:00 
1  1 days, 00:00:00 
2  2 days, 00:00:00 
3  3 days, 00:00:00 
4  4 days, 00:00:00 
5  5 days, 00:00:00 
6  6 days, 00:00:00 
7  7 days, 00:00:00 
8  8 days, 00:00:00 
9  9 days, 00:00:00 
10   00:00:00 

47 6 days, 00:00:00 
48 7 days, 00:00:00 
49 8 days, 00:00:00 
50 9 days, 00:00:00 
Length: 51, dtype: timedelta64[ns] 

तारीख को similary निर्माण किया है ऊपर

date = pd.Series(df.index) - pd.Series([ timedelta(int(i)) for i in d ]) 
df.groupby(date.values).mean() 
अधिक सामान्य मामले के लिए
+0

यह 10.1 में नहीं है, मैं dev संस्करण नहीं चला रहा हूँ।भविष्य के लिए जानना अच्छा है, धन्यवाद! –

संबंधित मुद्दे