2017-02-15 97 views
3

我有一個數據幀與一個整數值,SESSION_ID,事件和TIME_STAMP看起來像這樣:熊貓時間戳差值變換

In [41]: df = pd.DataFrame(data={'session_id': np.sort(np.random.choice(np.arange(3), 11)), 'event': np.random.choice(['A', 'B', 'C', 'D'], 11), 'time_stamp': pd.date_range 
    ...: ('1/1/2017', periods=11, freq='S')}).reset_index(drop=True) 

In [42]: df 
Out[42]: 
    event session_id   time_stamp 
0  B   0 2017-01-01 00:00:00 
1  C   0 2017-01-01 00:00:01 
2  D   0 2017-01-01 00:00:02 
3  B   1 2017-01-01 00:00:03 
4  B   1 2017-01-01 00:00:04 
5  D   2 2017-01-01 00:00:05 
6  B   2 2017-01-01 00:00:06 
7  A   2 2017-01-01 00:00:07 
8  B   2 2017-01-01 00:00:08 
9  B   2 2017-01-01 00:00:09 
10  A   2 2017-01-01 00:00:10 

我要計算使用groupby會話長度和lambda功能,但是我想返回一個與原始數據幀相同索引的系列對象,所以我可以將其添加爲列。這應該是可能的groupby.transform這樣的,但它返回一個奇怪的「不能轉換對象numpy的日期時間」的錯誤:

In [44]: df.groupby('session_id')['time_stamp'].transform(lambda x: x.max() - x.min()) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-44-c67ed1d4a90e> in <module>() 
----> 1 df.groupby('session_id')['time_stamp'].transform(lambda x: x.max() - x.min()) 

/Users/hendele/anaconda2/lib/python2.7/site-packages/pandas/core/groupby.pyc in transform(self, func, *args, **kwargs) 
    2843 
    2844    indexer = self._get_index(name) 
-> 2845    result[indexer] = res 
    2846 
    2847   result = _possibly_downcast_to_dtype(result, dtype) 

ValueError: Could not convert object to NumPy datetime 

我想我是不正確的使用。但是,當你使用groupby.agg,它的作品!

In [43]: df.groupby('session_id')['time_stamp'].agg(lambda x: x.max() - x.min()) 
Out[43]: 
session_id 
0 00:00:02 
1 00:00:01 
2 00:00:05 
Name: time_stamp, dtype: timedelta64[ns] 

你能解釋一下,如果這是一個錯誤,如果不是,我做錯了什麼?謝謝!

p.s.不想使用時間戳索引,因爲我可能在實際數據中有重複的時間戳。

+0

PR已被合併,修復應該在'0.20.0'。 –

回答

1

爲什麼agg工作但transform失敗?

這兩種行爲之間的區別在於transform()操作需要返回一個類似索引的操作。爲了促進這一點,transform從原始系列的副本開始。然後,在對每個組進行計算之後,將複製系列的適當元素設置爲等於結果。此時進行類型比較,並發現timedelta未能投射到datetimeagg()不執行此步驟,因此不會失敗類型檢查。

周圍的工作:

這個分析表明周圍的工作。如果transform的結果是datetime,它將會成功。所以要解決:

base_time = df['time_stamp'][0] 
df.groupby('session_id')['time_stamp'].transform(
    lambda x: x.max() - x.min() + base_time) - base_time 

這是一個錯誤嗎?

我認爲這是一個錯誤,我打算在早上提出問題。我將在此處更新問題鏈接。

更新:

我已經提交了bug並針對此問題的pull request