2013-08-22 2 views
-2

У меня массивный блок данных с четырьмя столбцами, два из которых являются «датой» (в формате datetime) и «страницей» (местоположение сохранено как string). Я сгруппировал dataframe на «странице» и назвал его pagegroup и хочу знать диапазон времени, по которому осуществляется обращение к каждой странице (например, первый доступ был на 1-1-13, последний на 1-5-13, поэтому max-min составляет 5 дней).Расчет date_range над объектом GroupBy в pandas

Я знаю, что в панд я могу использовать date_range для сравнения двух DateTimes, но пытается что-то вроде:

pagegroup['date'].agg(np.date_range) 

возвращается

AttributeError: 'module' object has no attribute 'date_range' 

при попытке простой (не даты конкретных) Numpy функции ptp дает мне целостный ответ:

daterange = pagegroup['date'].agg([np.ptp]) 
daterange.head() 

          ptp 
page       
%2F       0 
/   13325984000000000 
/-509606456 297697000000000 
/-511484155     0 
/-511616154     0 

Может кто-нибудь подумать способ рассчитать диапазон дат и вернуть его в распознаваемый формат даты?

Спасибо

+1

[ 'date_range'] (http://pandas.pydata.org/pandas-docs/stable/timeseries. html # time-series-date-function) - это функция pandas (так что это 'pd.date_range' не' np'), но она не сравнивает два времени. –

ответ

1

Предполагая, что вы индексируются DateTime можно использовать GroupBy применять:

In [11]: df = pd.DataFrame([[1, 2], [1, 3], [2, 4]], 
          columns=list('ab'), 
          index=pd.date_range('2013', freq='H', periods=3) 



In [12]: df 
Out[12]: 
        a b 
2013-08-22 00:00:00 1 2 
2013-08-22 01:00:00 1 3 
2013-08-22 02:00:00 2 4 

In [13]: g = df.groupby('a') 

In [14]: g.apply(lambda x: x.iloc[-1].name - x.iloc[0].name) 
Out[14]: 
a 
1 01:00:00 
2 00:00:00 
dtype: timedelta64[ns] 

Здесь iloc[-1] захватывает последнюю строку в группе и iloc[0] получает первый. Атрибут name - это индекс строки.

@Elyase указывает на то, что это работает только если оригинал DatetimeIndex был в порядке, если вы не можете использовать макс/мин (который на самом деле читает лучше, но может быть менее эффективным):

In [15]: g.apply(lambda x: x.index.max() - x.index.min()) 
Out[15]: 
a 
1 01:00:00 
2 00:00:00 
dtype: timedelta64[ns] 

Примечание : чтобы получить timedelta между двумя отметками времени, мы только что вычитали (-).

Если дата представляет собой столбец, а не индекс, а затем использовать имя столбца:

g.apply(lambda x: x['date'].iloc[-1] - x['date'].iloc[0]) 
g.apply(lambda x: x['date'].max() - x['date'].min()) 
+0

Возможно, вам нужно отсортировать группы, я думаю, он хочет получить самую раннюю и последнюю дату в каждой группе. – elyase

+0

@elyase tbh не на 100% уверен, какой желаемый результат. О, я думаю, что вижу, что вы предлагаете, вышеупомянутое предполагает, что DatetimeIndex упорядочен. Хорошая точка зрения. Будет обновляться с max и min. –