Диапазон дат Pandas возвращает «не удалось преобразовать строку в метку времени» для yyyy-ww

У меня есть фрейм данных с двумя столбцами; 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 недели в будущем.

Похоже, вы ссылаетесь на неправильный объект, в своем вопросе выше вы вставляете новый фрейм данных в data, но в своей строке pd.data_range вы вызываете ds. Попробуйте это: ds_pred = pd.date_range(start=data.min(), periods=len(data) + num_pred_weeks, freq = "W")

Erfan 27.05.2019 15:08

Не могли бы вы проверить тип столбца Date после этого вашего шага: data = dataset.groupby(['Date'])["Sales"].sum().reset_index() это тип объекта?

AT_asks 27.05.2019 15:10

Странный баг :(

jezrael 27.05.2019 15:10

@Erfan Извините, забыл добавить немного кода! Виноват

Artem 27.05.2019 15:11

@AT_asks да, это DataFrame

Artem 27.05.2019 15:11

@Artem, я имел в виду тип столбца (Object/int/float...)

AT_asks 27.05.2019 15:50
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
6
7 073
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я думаю, проблема в том, что нужно создать минимум 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 27.05.2019 15:19

@Erfan - это другое, я нахожу разницу здесь

jezrael 27.05.2019 15:20

@Erfan прав - я просто хочу увеличивать еженедельные данные (используя pd.date_range или какой-либо другой метод). Похоже, он не распознает форматирование как формат yyyy-ww.

Artem 27.05.2019 15:23

@Artem - да, нужно дату и время в формате YYYY-MM-DD.

jezrael 27.05.2019 15:24

@jezrael - Арх, теперь понятно. Подождите, возможно, я смогу использовать ваше второе решение.

Artem 27.05.2019 15:26

@Artem - да, или последнее - просто используйте минимум исходных данных - в формате дата и время YYYY-MM-DD

jezrael 27.05.2019 15:26

Если 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")

Другие вопросы по теме