Pythonic способ отобразить форматируемый столбец yyyymm в числовой столбец? - PullRequest
0 голосов
/ 11 февраля 2019

Извините, если в названии не совсем ясно, но дело в том, что у меня есть Pandas DataFrame со следующим столбцом Date:

 Date
201611
201612
201701

И я хочу отобразить это, поэтому у меня естьстолбец периода, который принимает значение 1 для первого периода, а затем начинает отсчитывать один за другим до последнего периода, например, так:

 Date     Period
201611      1
201612      2
201701      3

Я добился того, чего хочу:

dic_t={}
for n,t in enumerate(sorted(df.Date.unique())):
    dic_t[t]=n+1
df['Period']=df.Date.map(dic_t)

Но это не кажется слишком питоническим.Я думаю, я мог бы достичь чего-то подобного, используя словарные понимания, но я не очень хорош в них пока .

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

pd.factorize может сортировать список элементов и возвращать уникальные целочисленные метки:

In [209]: pd.factorize(['201611','201612','201701','201702','201704','201612'], sort=True)[0]+1
Out[209]: array([1, 2, 3, 4, 5, 2])

Поэтому вы можете использовать

df['Period'] = pd.factorize(df['Date'], sort=True)[0] + 1

pd.factorize возвращает как массив меток, так и массив уникальных значений:

In [210]: pd.factorize(['201611','201612','201701','201702','201704','201612'], sort=True)
Out[210]: 
(array([0, 1, 2, 3, 4, 1]),
 array(['201611', '201612', '201701', '201702', '201704'], dtype=object))

Поскольку в этом вопросе кажется, что вам нужны только метки, я использовал pd.factorize(...)[0], чтобы получить только метки.

0 голосов
/ 11 февраля 2019

Таким образом, на основе информации из вопроса и комментариев, нумерация периодов (комбинаций года и месяца) должна начинаться с первого периода, который присутствует в кадре данных.

Для этой цели, ваш код работает просто отлично.Если вы думаете, что dict понимания выглядят «более питоническими», вы можете выразить это как:

period_dict = {
    period: i+1
    for i, period in enumerate(sorted(df.Date.unique()))}
df['Period'] = df.Date.map(period_dict)

Просто обратите внимание: с помощью этого метода, если по какой-то причине нет никаких точек данных длячерез месяц после начального месяца этому месяцу не будет присвоен номер периода.Например, если у вас нет данных за март 2017 года, то:

 Date     Period
201611      1
201612      2
201701      3
201702      4
201704      5       <== April is period 5 and not 6

Если вам нужно создать полное перечисление для всех возможных периодов, используйте что-то вроде этого:

start_year = 2016
end_year = 2018
period_list = [
    y*100 + m
    for y in range(start_year, end_year+1)
    for m in range(1, 13)]
period_dict = {
    period: i+1
    for i, period in enumerate(period_list)}

df['Period'] = df.Date.map(period_dict)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...