Панды: DataFrame groupby для года / месяца и возврат с новым DatetimeIndex
Мне нужно несколько направлений в группировке панд DateFrame
возьмите год или месяц и получите взамен новый DateFrame
объект с новым индексом. Вот мой код до сих пор. groupby
работает как задумано.
Загрузите данные из CSV-файла, проанализируйте формат "Дата" и формат даты (исторические котировки акций на сайте finance.yahoo.com).
In [23]: import pandas as pd
file = pd.read_csv("sdf.de.csv", parse_dates=['Date'])
file.head(2)
Out[23]:
Date Open High Low Close Volume Adj Close
0 2016-02-16 18.650 18.70 17.940 18.16 1720800 17.0600
1 2016-02-15 18.295 18.64 18.065 18.50 1463500 17.3794
Сортировать файл по возрастанию "Дата" и установить индекс в Date
In [24]: daily = file.sort_values(by='Date').set_index('Date')
daily.head()
Out[24]:
Open High Low Close Volume Adj Close
Date
2000-01-03 14.20 14.50 14.15 14.40 277400 2.7916
2000-01-04 14.29 14.30 13.90 14.15 109200 2.7431
группировка по месяцам
Я бы сделал дополнительный apply()
к группам, которые будут конденсировать данные для конкретной группы, например, найти самый высокий High
значение за год / месяц или sum()
Volume
ценности. Этот шаг опущен для этого примера.
In [39]: monthly = daily.groupby(lambda x: (x.year, x.month))
monthly.first()
Out[39]:
Open High Low Close Volume Adj Close
(2000, 1) 14.200 14.500 14.150 14.400 277400 2.7916
(2000, 2) 13.900 14.390 13.900 14.250 287200 2.7625
... ... ... ... ... ... ...
(2016, 1) 23.620 23.620 23.620 23.620 0 22.1893
(2016, 2) 19.575 19.630 19.140 19.450 1783000 18.2719
Это работает, но это дает мне DateFrame
объект с кортежем в качестве индекса.
Желаемый результат, в данном случае для группировки по месяцам, будет полностью новым DataFrame
объект, но Date
индекс должен быть новым DatetimeIndex
в виде %Y-%m
или просто %Y
если сгруппированы по годам.
Out[39]:
Open High Low Close Volume Adj Close
Date
2000-01 14.200 14.500 14.150 14.400 277400 2.7916
2000-02 13.900 14.390 13.900 14.250 287200 2.7625
... ... ... ... ... ... ...
2016-01 23.620 23.620 23.620 23.620 0 22.1893
2016-02 19.575 19.630 19.140 19.450 1783000 18.2719
Я благодарен за любые указания.
2 ответа
Ты можешь использовать groupby
с daily.index.year, daily.index.month
или изменить index
to_period
а потом groupby
от index
:
print daily
Open High Low Close Volume Adj Close
Date
2000-01-01 14.200 14.50 14.15 14.40 277400 2.7916
2000-02-01 13.900 14.39 13.90 14.25 287200 2.7625
2016-01-01 23.620 23.62 23.62 23.62 0 22.1893
2016-02-01 19.575 19.63 19.14 19.45 1783000 18.2719
print daily.groupby([daily.index.year, daily.index.month]).first()
Open High Low Close Volume Adj Close
2000 1 14.200 14.50 14.15 14.40 277400 2.7916
2 13.900 14.39 13.90 14.25 287200 2.7625
2016 1 23.620 23.62 23.62 23.62 0 22.1893
2 19.575 19.63 19.14 19.45 1783000 18.2719
daily.index = daily.index.to_period('M')
print daily.groupby(daily.index).first()
Open High Low Close Volume Adj Close
Date
2000-01 14.200 14.50 14.15 14.40 277400 2.7916
2000-02 13.900 14.39 13.90 14.25 287200 2.7625
2016-01 23.620 23.62 23.62 23.62 0 22.1893
2016-02 19.575 19.63 19.14 19.45 1783000 18.2719
Вы можете использовать понимание списка, чтобы получить доступ к переменной доступа года и месяца из ваших временных меток, а затем сгруппировать их.
>>> df.groupby([[d.year for d in df.Date], [d.month for d in df.Date]]).first()
Date Open High Low Close Volume Adj_Close
2000 1 2000-01-01 14.200 14.50 14.15 14.40 277400 2.7916
2 2000-02-01 13.900 14.39 13.90 14.25 287200 2.7625
2016 1 2016-01-01 23.620 23.62 23.62 23.62 0 22.1893
2 2016-02-01 19.575 19.63 19.14 19.45 1783000 18.2719