#python #date #pandas #dataframe
#python #Дата #pandas #фрейм данных
Вопрос:
У меня есть фрейм данных, который находится в этом формате.
country_txt multiple success nkill nwound property dates
1970Q1 Italy 0 1 0.0 0.0 0 1970-01-01
1970Q1 Italy 0 0 0.0 0.0 1 1970-01-01
1970Q4 Italy 0 0 0.0 0.0 1 1970-04-01
1971Q1 Italy 0 1 0.0 0.0 1 1971-01-01
1971Q3 Italy 0 1 0.0 0.0 1 1971-03-01
Индекс этого фрейма данных — это год, за которым следует квартал, который я создал с помощью PeriodIndex
. dates
Столбец также символизирует год и квартал, день месяца не имеет значения. Я хочу суммировать все остальные столбцы за каждый квартал. Обычно это не проблема, поскольку я могу просто сделать italy.groupby('dates').sum()
. Однако результат, который я получаю, таков
multiple success nkill nwound property
dates
1970-01-01 0 1 0.0 0.0 1
1970-04-01 0 0 0.0 0.0 1
1971-01-01 0 1 0.0 0.0 1
Проблема в том, что теперь я хочу заполнить недостающие значения для каждого квартала, который не отображается, чтобы результат выглядел примерно так,
multiple success nkill nwound property
dates
1970-01-01 0 1 0.0 0.0 1
1970-02-01 0 0 0.0 0.0 0
1970-03-01 0 0 0.0 0.0 0
1970-04-01 0 0 0.0 0.0 1
1971-01-01 0 1 0.0 0.0 1
Я просмотрел предыдущие вопросы и обнаружил, что люди рекомендуют мне делать это df.reindex(pd.date_range("1970-01-01", "2015-12-31"), fill_value = 0)
. Проблема в том, что это даст моим данным много дополнительных строк, поскольку у меня будут данные на ежедневной основе, что тогда будет означать, что мне придется заново суммировать данные по кварталам. Итак, как бы я достиг этой цели, не создавая все эти ежедневные 0 и не находя способ снова суммировать все по кварталам?
Для справки, dates
столбец был создан путем первого изменения исходного столбца месяцев на значение от 1 до 4 (для обозначения квартала), а затем преобразован в формат timedelta, выполнив это
df['dates'] = df.iyear.astype(str).str.cat(df.imonth.astype(str))
df['dates'] = pd.to_datetime(df['dates'], format = '%Y%m')
Ответ №1:
ОБНОВЛЕНИЕ: анализ реальных дат из строкового индекса. Это должно работать и для более старых версий Pandas:
In [212]: df.set_index(pd.to_datetime(df.index)).resample('QS').sum().fillna(0)
Out[212]:
multiple success nkill nwound property
idx
1970-01-01 0.0 1.0 0.0 0.0 1.0
1970-04-01 0.0 0.0 0.0 0.0 0.0
1970-07-01 0.0 0.0 0.0 0.0 0.0
1970-10-01 0.0 0.0 0.0 0.0 1.0
1971-01-01 0.0 1.0 0.0 0.0 1.0
1971-04-01 0.0 0.0 0.0 0.0 0.0
1971-07-01 0.0 1.0 0.0 0.0 1.0
СТАРЫЙ ответ: (предполагая, что dates
столбец содержит реальные даты). Он использует новую функцию Pandas 0.19.0: .resample(..., on='column_name')
:
попробуйте это:
In [205]: df.resample('QS', on='dates').sum().fillna(0)
Out[205]:
multiple success nkill nwound property
dates
1970-01-01 0.0 1.0 0.0 0.0 1.0
1970-04-01 0.0 0.0 0.0 0.0 1.0
1970-07-01 0.0 0.0 0.0 0.0 0.0
1970-10-01 0.0 0.0 0.0 0.0 0.0
1971-01-01 0.0 2.0 0.0 0.0 2.0
или повторная выборка «ежемесячно»:
In [207]: df.resample('QS', on='dates').sum().resample('MS').sum().fillna(0)
Out[207]:
multiple success nkill nwound property
dates
1970-01-01 0.0 1.0 0.0 0.0 1.0
1970-02-01 0.0 0.0 0.0 0.0 0.0
1970-03-01 0.0 0.0 0.0 0.0 0.0
1970-04-01 0.0 0.0 0.0 0.0 1.0
1970-05-01 0.0 0.0 0.0 0.0 0.0
1970-06-01 0.0 0.0 0.0 0.0 0.0
1970-07-01 0.0 0.0 0.0 0.0 0.0
1970-08-01 0.0 0.0 0.0 0.0 0.0
1970-09-01 0.0 0.0 0.0 0.0 0.0
1970-10-01 0.0 0.0 0.0 0.0 0.0
1970-11-01 0.0 0.0 0.0 0.0 0.0
1970-12-01 0.0 0.0 0.0 0.0 0.0
1971-01-01 0.0 2.0 0.0 0.0 2.0
Комментарии:
1. Я получаю эту ошибку
TypeError: resample() got an unexpected keyword argument 'on'
. И просто для ясности, я выполняю эту команду для фрейма данных, для которого я уже использовалgroupby
функцию, это правильно?2. Я использую новую версию Pandas: 0.19.0.
resample(on='col_name')
— это новая функция Pandas 0.19.03. Новых функций 1.. что ж, 1 за хороший ответ и ура! новые возможности.
4. Я смог использовать ваше решение, изменив
on
наaxis = 0
. Спасибо за вашу помощь!5. Я полагаю, что из-за проблем с совместимостью другой библиотеки, которую я использую, которая находится на стадии разработки, моя версия Pandas должна оставаться старой из-за проблем со стабильностью.