Как получить упорядоченное количество названий месяцев из индекса даты и времени

#python #pandas #dataframe #datetime

#python #pandas #dataframe #datetime

Вопрос:

У меня есть фрейм данных с именем WorkOrders, который выглядит следующим образом

введите описание изображения здесь

что я хочу сделать, так это преобразовать формат метки времени в индексе, чтобы индекс считывался как 2018-Feb-27 10:47:00.

Затем я могу вызвать метод для подсчета количества строк в каждом месяце. Следующий метод с использованием лямбда-выражения и group by возвращает

введите описание изображения здесь

По сути, это то, что я пытаюсь сделать, за исключением того, что 1 становится январем, 2 становится февральским и т. Д. Использование .month_name() метода работает, но оно больше не в хронологическом порядке, например

введите описание изображения здесь

Это то, что я хотел бы видеть, за исключением порядка января, февраля, марта….

Ответ №1:

  • Желаемый формат, '2018-Feb-27 10:47:00' , str не является a datetime64[ns] dtype , что означает df.index.month и df[col].dt.month не может использоваться для извлечения месяца, потому что эти методы не работают strings .

Вариант 1:

  • Я думаю, что проще использовать calendar модуль (часть стандартной библиотеки), чтобы получить list имена месяцев, а затем сопоставить номер месяца с названием месяца.
 import pandas as pd
from calendar

# test dataframe
df = pd.DataFrame({'a': np.random.randint(1, 10, size=(3000))}, index=pd.bdate_range('2021-01-21', freq='D', periods=3000))
df.index.name = 'Call Out Time'

# display(df.head())
               a
Call Out Time   
2021-01-21     3
2021-01-22     8
2021-01-23     7
2021-01-24     2
2021-01-25     9

# groupby month: the index must be a datetime dtype
dfg = df.groupby(df.index.month).size().reset_index(name='counts')

# map the month number to the month name
dfg['Call Out Time'] = dfg['Call Out Time'].map(dict(zip(range(1, 13), calendar.month_name[1:])))
 

Вариант 2:

  • В вашей существующей реализации используйте pandas.Categorical , with ordered=True .
 # groupby month_name
dfg = df.groupby(df.index.month_name()).size().reset_index(name='counts')

# set as categorical
dfg['Call Out Time'] = pd.Categorical(dfg['Call Out Time'], categories=calendar.month_name[1:], ordered=True)

# sort the values
dfg = dfg.sort_values('Call Out Time').reset_index(drop=True)
 

Результат обоих вариантов:

    Call Out Time  counts
0        January     259
1       February     254
2          March     279
3          April     248
4            May     248
5           June     240
6           July     248
7         August     248
8      September     240
9        October     248
10      November     240
11      December     248