अपने कोड (आपके groupby/apply
) के आधार पर, ऐसा लगता है (आपके उदाहरण के बावजूद ... लेकिन हो सकता है कि मैं आपको क्या समझना चाहूंगा और फिर एंडी क्या सबसे अच्छा विचार होगा) कि आप 'डेट' के साथ काम कर रहे हैं कॉलम जो datetime64
dtype है और आपके वास्तविक डेटा में integer
dtype नहीं है। ऐसा लगता है कि आप दिए गए group/stage
के पहले अवलोकन से मापा गया दिनों में परिवर्तन की गणना करना चाहते हैं। मुझे लगता है कि इस उदाहरण डेटा का एक बेहतर सेट है (अगर मैं सही ढंग से अपने लक्ष्य को समझने):
>>> df
group date stage dur
0 A 2014-01-01 one 0
1 A 2014-01-03 one 2
2 A 2014-01-04 one 3
3 A 2014-01-05 two 0
4 B 2014-01-02 four 0
5 B 2014-01-06 five 0
6 B 2014-01-10 five 4
7 C 2014-01-03 two 0
8 C 2014-01-05 two 2
यह देखते हुए कि तुम सिर्फ भाग देकर अपना लागू (के रूप में जेफ उसकी टिप्पणी में पता चलता है) को संशोधित करने से कुछ गति-अप मिलना चाहिए के माध्यम से द्वारा एक vectorized तरह से timedelta64
के बाद लागू (या आप लागू में यह कर सकता है):
>>> df['dur'] = df.groupby(['group','stage']).date.apply(lambda x: x - x.iloc[0])
>>> df['dur'] /= np.timedelta64(1,'D')
>>> df
group date stage dur
0 A 2014-01-01 one 0
1 A 2014-01-03 one 2
2 A 2014-01-04 one 3
3 A 2014-01-05 two 0
4 B 2014-01-02 four 0
5 B 2014-01-06 five 0
6 B 2014-01-10 five 4
7 C 2014-01-03 two 0
8 C 2014-01-05 two 2
लेकिन क्या आप भी बच सकते हैं groupby/apply
अपने डेटा को देखते हुए समूह, मंच, तिथि के क्रम में है। प्रत्येक ['group','stage']
समूहिंग के लिए पहली तारीख तब होती है जब समूह बदलता है या चरण बदलता है। तो मुझे लगता है आप निम्नलिखित की तरह कुछ कर सकते हैं:
>>> beg = (df.group != df.group.shift(1)) | (df.stage != df.stage.shift(1))
>>> df['dur'] = (df['date'] - df['date'].where(beg).ffill())/np.timedelta64(1,'D')
>>> df
group date stage dur
0 A 2014-01-01 one 0
1 A 2014-01-03 one 2
2 A 2014-01-04 one 3
3 A 2014-01-05 two 0
4 B 2014-01-02 four 0
5 B 2014-01-06 five 0
6 B 2014-01-10 five 4
7 C 2014-01-03 two 0
8 C 2014-01-05 two 2
स्पष्टीकरण: नोट क्या df['date'].where(beg)
बनाता है:
>>> beg = (df.group != df.group.shift(1)) | (df.stage != df.stage.shift(1))
>>> df['date'].where(beg)
0 2014-01-01
1 NaT
2 NaT
3 2014-01-05
4 2014-01-02
5 2014-01-06
6 NaT
7 2014-01-03
8 NaT
और फिर मैं मान ffill
और 'तारीख' कॉलम के साथ अंतर ले।
संपादित करें: एंडी बताते के रूप में आप भी transform
इस्तेमाल कर सकते हैं:
>>> df['dur'] = df.date - df.groupby(['group','stage']).date.transform(lambda x: x.iloc[0])
>>> df['dur'] /= np.timedelta64(1,'D')
group date stage dur
0 A 2014-01-01 one 0
1 A 2014-01-03 one 2
2 A 2014-01-04 one 3
3 A 2014-01-05 two 0
4 B 2014-01-02 four 0
5 B 2014-01-06 five 0
6 B 2014-01-10 five 4
7 C 2014-01-03 two 0
8 C 2014-01-05 two 2
स्पीड: मैं 400,000 टिप्पणियों के साथ एक समान dataframe का उपयोग कर दो विधि का समय समाप्त हो:
विधि लागू करें:
1 loops, best of 3: 18.3 s per loop
गैर-लागू विधि:
1 loops, best of 3: 1.64 s per loop
तो मैं परहेज लगता है कि कुछ महत्वपूर्ण गति-अप
आप अंतिम लागू की जरूरत नहीं है यहाँ देखने दे सकता है लागू होते हैं: http://pandas-docs.github.io/pandas-docs -travis/timeseries.html # समय-डेल्टा-रूपांतरण, आप बस '' टाइप टाइप कर सकते हैं ('timedelta64 [D]') '' या np.timedelta64 (1, 'डी') द्वारा विभाजित करें '(वे sligthly हैं वे कैसे दौर में अलग हैं। – Jeff