Pandas: преобразовать интервал дат в обычную дату

Как изменить дату, выраженную в виде интервала, чтобы она выражалась в обычном формате %Y-%M-%D.

Первоначально у меня был df, который выглядел так:

   Id       Date  Quantity
1000A 2018-03-22      20.0
1000A 2018-03-29       8.0
1000A 2018-03-27       4.0
1000A 2018-03-28      10.0


или:

all_data = pd.DataFrame({'Id': ['1000A','1000A','1000A','1000A'], 'Date': ['2018-03-28', '2018-04-12', '2018-05-02', '2018-06-28'], 'Quantity' : [20.0, 8.0, 4.0, 10.0]})

all_data.Date = pd.to_datetime(all_data.Date)

Я применил к нему материал, чтобы получить даты, сгруппированные по месяцам, начиная с сегодняшней даты.

today1 = pd.to_datetime('today').normalize()
frequency1 = '30D'
Nbin1 = (today1 - all_data['Date'].min()) // pd.Timedelta(frequency1) + 1  # Number of bins
bins1 = [today1 - n * pd.Timedelta(frequency1) for n in range(Nbin1, -1, -1)]
data11 = all_data.groupby(['Id', pd.cut(all_data['Date'], bins=bins1)]).sum().fillna(0).reset_index()

вывод выглядит так:

        Id                      Date  Quantity
0   1000A  (2018-03-02, 2018-04-01]     20.0
1   1000A  (2018-04-01, 2018-05-01]      8.0
2   1000A  (2018-05-01, 2018-05-31]      4.0
3   1000A  (2018-05-31, 2018-06-30]     10.0
....
n.  1000A  (2020-11-16, 2020-12-16]     0.0

Я не могу найти способ преобразовать столбец даты обратно в обычный формат даты, например:

      Date   
2018-04-01   
2018-05-01   
2018-05-31   
2018-06-30   

Я чувствую, что перепробовал все инструменты, которые смог найти, но ничего не помогает, любая помощь будет оценена по достоинству.

Почему в 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
0
331
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

У вас есть категориальный dtype в Date. Один из способов справиться с этим — преобразовать его в str, чтобы вы могли извлечь нужный шаблон, а затем преобразовать его в datetime:

data11['Date'] = data11.Date.astype(str).str.extract(', (.+?)]').astype('datetime64[ns]')

чудо! Спасибо! я пытался использовать astype(str).split(), чтобы решить эту проблему, но это не сработало, не могли бы вы сказать мне, почему повторение str - это путь?

Murcielago 16.12.2020 02:02

Конечно! Чтобы получить доступ к любому методу str в серии pandas, вам нужно использовать его, точно так же, как вы должны использовать dt для доступа к свойствам даты и времени в серии.

Cainã Max Couto-Silva 16.12.2020 02:05

С другой стороны, если вы получаете доступ к одному значению из серии, например data11.Date.astype(str)[0], вы можете (и должны) использовать метод str напрямую.

Cainã Max Couto-Silva 16.12.2020 02:08

Я понимаю, супер полезно, спасибо!

Murcielago 16.12.2020 02:10

@Peyo и Caina, это неправильный способ извлечения значений из Interval: type(data11.iloc[0, 1]) → pandas._libs.interval.Interval. Смотрите дубликат. data11.Date = pd.IntervalIndex(data11.Date).right или data11.Date = data11.Date.apply(lambda x: x.right), однако первый вариант векторизован.

Trenton McKinney 16.12.2020 02:30

Привет, @TrentonMcKinney! Спасибо, что указали лучший способ и более подходящий способ сделать это. Я полностью согласен с вами в этом, хотя я также не согласен с такими утверждениями, как «правильный путь», поскольку несколько подходов могут прекрасно работать для достижения одной и той же цели (как в этом случае). Тем не менее, вы только что расширили наши знания, так что еще раз спасибо!

Cainã Max Couto-Silva 16.12.2020 02:41

Рад, что информативно. Кроме того, я говорю правильно в том смысле, что это правильный способ использования аксессора .dt для работы с данными даты и времени. Таким образом, это «правильный способ» использовать методы Interval для извлечения левого или правого предела. Признано, что может быть более одного способа, но это ссылка на Дзен Python (import this). Должен быть один - и желательно только один - очевидный способ сделать это. Счастливых праздников!

Trenton McKinney 16.12.2020 02:50

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