#python #pandas #time-series #frequency
#python #pandas #временные ряды #частота
Вопрос:
У меня есть серия Pandas следующим образом :
2014-05-24 23:59:49 1.3
2014-05-24 23:59:50 2.17
2014-05-24 23:59:50 1.28
2014-05-24 23:59:51 1.30
2014-05-24 23:59:51 2.17
2014-05-24 23:59:53 2.17
2014-05-24 23:59:58 2.17
Name: api_id, Length: 483677
Я пытаюсь подсчитать для каждого идентификатора частоту в день.
На данный момент я делаю это :
count = {}
for x in apis.unique():
count[x] = apis[apis == x].resample('D','count')
count_df = pd.DataFrame(count)
Это дает мне то, что я хочу, а именно :
... 2.13 2.17 2.4 2.6 2.7 3.5(user) 3.9 4.2 5.1 5.6
timestamp ...
2014-05-22 ... 391 49962 3727 161 2 444 113 90 1398 90
2014-05-23 ... 450 49918 3861 187 1 450 170 90 629 90
2014-05-24 ... 396 46359 3603 172 3 513 171 89 622 90
Но есть ли способ сделать это без цикла for ?
Ответ №1:
Вы можете использовать value_counts
функцию для этого (docs), применив это после groupby (что аналогично resample('D')
тому, что вы сделали, но повторная выборка ожидает агрегированный результат, поэтому в этом случае мы должны использовать более общий groupby). С небольшим примером:
In [16]: s = pd.Series([1,1,2,2,1,2,5,6,2,5,4,1], index=pd.date_range('2012-01-01', periods=12, freq='8H'))
In [17]: counts = s.groupby(pd.Grouper(freq='D')).value_counts()
In [18]: counts
Out[18]:
2012-01-01 1 2
2 1
2012-01-02 2 2
1 1
2012-01-03 2 1
6 1
5 1
2012-01-04 1 1
5 1
4 1
dtype: int64
Чтобы получить это в желаемом формате, вы можете просто распаковать это (переместить индексы строк второго уровня в столбцы):
In [19]: counts.unstack()
Out[19]:
1 2 4 5 6
2012-01-01 2 1 NaN NaN NaN
2012-01-02 1 2 NaN NaN NaN
2012-01-03 NaN 1 NaN 1 1
2012-01-04 1 NaN 1 1 NaN
Примечание: для использования groupby(pd.Grouper(freq='D'))
вам нужен pandas 0.14. Если у вас есть более старая версия, вы можете использовать groupby(pd.TimeGrouper(freq='D'))
для получения точно такой же. Это также похоже на выполнение groupby(s.index.date)
(с той разницей, что у вас есть datetime.date
объекты в индексе).
Комментарии:
1. Большое спасибо, именно то, что я хотел!