У меня есть фрейм данных с двумя столбцами; Sales
и Date
.
dataset.head(10)
Date Sales
0 2015-01-02 34988.0
1 2015-01-03 32809.0
2 2015-01-05 9802.0
3 2015-01-06 15124.0
4 2015-01-07 13553.0
5 2015-01-08 14574.0
6 2015-01-09 20836.0
7 2015-01-10 28825.0
8 2015-01-12 6938.0
9 2015-01-13 11790.0
Я хочу преобразовать столбец Date
из yyyy-mm-dd
(например, 2015-06-01
) в yyyy-ww
(например, 2015-23
), поэтому запускаю следующий фрагмент кода:
dataset["Date"] = pd.to_datetime(dataset["Date"]).dt.strftime('%Y-%V')
Затем я группирую по Sales
по неделям, т.е.
data = dataset.groupby(['Date'])["Sales"].sum().reset_index()
data.head(10)
Date Sales
0 2015-01 67797.0
1 2015-02 102714.0
2 2015-03 107011.0
3 2015-04 121480.0
4 2015-05 148098.0
5 2015-06 132152.0
6 2015-07 133914.0
7 2015-08 136160.0
8 2015-09 185471.0
9 2015-10 190793.0
Теперь я хочу создать диапазон дат на основе столбца Date
, так как я прогнозирую продажи по неделям:
ds = data.Date.values
ds_pred = pd.date_range(start=ds.min(), periods=len(ds) + num_pred_weeks,
freq = "W")
Однако я получаю следующую ошибку: could not convert string to Timestamp
которую я не совсем уверен, как исправить. Итак, если я использую 2015-01-01
в качестве даты начала моего импорта даты, я не получаю ошибки, что заставляет меня понять, что я неправильно использую функции. Однако я не уверен, как?
Я хотел бы в основном иметь диапазон дат, который еженедельно охватывает текущую неделю, а затем 52 недели в будущем.
Не могли бы вы проверить тип столбца Date после этого вашего шага: data = dataset.groupby(['Date'])["Sales"].sum().reset_index()
это тип объекта?
Странный баг :(
@Erfan Извините, забыл добавить немного кода! Виноват
@AT_asks да, это DataFrame
@Artem, я имел в виду тип столбца (Object/int/float...)
Я думаю, проблема в том, что нужно создать минимум dataset["Date"]
столбца, заполненного строками в формате YYYY-VV
. Но для перехода к date_range
нужен формат YYYY-MM-DD
или объект даты и времени.
Я нашел это:
Several additional directives not required by the C89 standard are included for convenience. These parameters all correspond to ISO 8601 date values. These may not be available on all platforms when used with the strftime() method. The ISO 8601 year and ISO 8601 week directives are not interchangeable with the year and week number directives above. Calling strptime() with incomplete or ambiguous ISO 8601 directives will raise a ValueError.
%V ISO 8601 week as a decimal number with Monday as the first day of the week. Week 01 is the week containing Jan 4.
Ошибка Pandas 0.24.2 с форматом YYYY-VV
:
dataset = pd.DataFrame({'Date':['2015-06-01','2015-06-02']})
dataset["Date"] = pd.to_datetime(dataset["Date"]).dt.strftime('%Y-%V')
print (dataset)
Date
0 2015-23
1 2015-23
ds = pd.to_datetime(dataset['Date'], format='%Y-%V')
print (ds)
ValueError: 'V' is a bad directive in format '%Y-%V'
Возможным решением является использование %U
или %W, проверьте это:
%U Week number of the year (Sunday as the first day of the week) as a zero padded decimal number. All days in a new year preceding the first Sunday are considered to be in week 0.
%W Week number of the year (Monday as the first day of the week) as a decimal number. All days in a new year preceding the first Monday are considered to be in week 0.
dataset = pd.DataFrame({'Date':['2015-06-01','2015-06-02']})
dataset["Date"] = pd.to_datetime(dataset["Date"]).dt.strftime('%Y-%U')
print (dataset)
Date
0 2015-22
1 2015-22
ds = pd.to_datetime(dataset['Date'] + '-1', format='%Y-%U-%w')
print (ds)
0 2015-06-01
1 2015-06-01
Name: Date, dtype: datetime64[ns]
Или используя данные из исходного DataFrame в datetime:
dataset = pd.DataFrame({'Date':['2015-06-01','2015-06-02'],
'Sales':[10,20]})
dataset["Date"] = pd.to_datetime(dataset["Date"])
print (dataset)
Date Sales
0 2015-06-01 10
1 2015-06-02 20
data = dataset.groupby(dataset['Date'].dt.strftime('%Y-%V'))["Sales"].sum().reset_index()
print (data)
Date Sales
0 2015-23 30
num_pred_weeks = 5
ds = data.Date.values
ds_pred = pd.date_range(start=dataset["Date"].min(), periods=len(ds) + num_pred_weeks, freq = "W")
print (ds_pred)
DatetimeIndex(['2015-06-07', '2015-06-14', '2015-06-21',
'2015-06-28',
'2015-07-05', '2015-07-12'],
dtype='datetime64[ns]', freq='W-SUN')
Не уверен, правильно ли я понимаю ОП, но разве он просто не хочет формат %Y-%W
?
@Erfan - это другое, я нахожу разницу здесь
@Erfan прав - я просто хочу увеличивать еженедельные данные (используя pd.date_range или какой-либо другой метод). Похоже, он не распознает форматирование как формат yyyy-ww.
@Artem - да, нужно дату и время в формате YYYY-MM-DD
.
@jezrael - Арх, теперь понятно. Подождите, возможно, я смогу использовать ваше второе решение.
@Artem - да, или последнее - просто используйте минимум исходных данных - в формате дата и время YYYY-MM-DD
Если ds
содержит даты в виде строки, отформатированной как '2015-01'
, которая должна быть '%Y-%W'
(или '%G-%V'
в библиотеке даты и времени), вы должны добавить номер дня, чтобы получить день. Здесь, предполагая, что вы хотите понедельник, вы должны:
ds_pred = pd.date_range(start=pd.to_datetime(ds.min() + '-1', format='%Y-%W-%w',
periods=len(ds) + num_pred_weeks, freq = "W")
Похоже, вы ссылаетесь на неправильный объект, в своем вопросе выше вы вставляете новый фрейм данных в
data
, но в своей строкеpd.data_range
вы вызываетеds
. Попробуйте это:ds_pred = pd.date_range(start=data.min(), periods=len(data) + num_pred_weeks, freq = "W")