Разделите имена столбцов и установите их в виде строк в Pandas - PullRequest
1 голос
/ 14 апреля 2020

С учетом следующего кадра данных:

         date  bj:quantity:dc  tj:quantity:hp
0   2007/9/30         27.6901            19.1
1  2007/12/31         25.2259            17.7
2   2008/3/31         24.0400            16.3
3   2008/6/30         15.0000            15.4
4   2008/9/30          0.0000            13.4

Допустим, имя столбца bj:quantity:dc содержит city и district, первая и последняя части, разделенные на :, соответственно city и district.

Как я могу преобразовать его в следующий формат? Спасибо.

         date city district  quantity
0   2007/9/30   bj       dc   27.6901
1  2007/12/31   bj       dc   25.2259
2   2008/3/31   bj       dc   24.0400
3   2008/6/30   bj       dc   15.0000
4   2008/9/30   bj       dc    0.0000
5   2007/9/30   tj       hp   19.1000
6  2007/12/31   tj       hp   17.7000
7   2008/3/31   tj       hp   16.3000
8   2008/6/30   tj       hp   15.4000
9   2008/9/30   tj       hp   13.4000

Ссылочный код:

#df.columns = df.columns.str.split(':', n=1, expand=True).droplevel(-1)
df.columns = df.columns.str.split(':', n=1, expand=True)

lvl = pd.CategoricalIndex(df.columns.levels[1], 
                              ordered=True, 
                              categories=df.columns.get_level_values(1).drop_duplicates())
df.columns = df.columns.set_levels(lvl, level=1)
df = df.stack().sort_index(level=[1, 0]).rename_axis(('date','city')).reset_index()

Ответы [ 2 ]

1 голос
/ 14 апреля 2020

просто еще одно решение, которое изменяет форму столбцов, а затем использует pandas ' от ширины до длины метод:

df.columns = [entry[3:]+'-'+entry[:2] if ':' in entry else entry for entry in df.columns ]

res = (pd.wide_to_long(df,stubnames='quantity',i='date',sep=':',j='extract',suffix='[a-z]{2}-[a-z]{2}')
       .reset_index()
       .assign(city = lambda x: x['extract'].str.split('-').str.get(-1),
               district = lambda x: x['extract'].str.split('-').str.get(0)
              )
       .drop('extract',axis = 1)
       .reindex(['date','city','district','quantity'],axis=1)
      )

res


     date     city  district    quantity
0   2007/9/30   bj  dc  27.6901
1   2007/12/31  bj  dc  25.2259
2   2008/3/31   bj  dc  24.0400
3   2008/6/30   bj  dc  15.0000
4   2008/9/30   bj  dc  0.0000
5   2007/9/30   tj  hp  19.1000
6   2007/12/31  tj  hp  17.7000
7   2008/3/31   tj  hp  16.3000
8   2008/6/30   tj  hp  15.4000
9   2008/9/30   tj  hp  13.4000
1 голос
/ 14 апреля 2020

Вы можете разделить на : на Multiindex все столбцы без date, для которого был задан индекс, затем DataFrame.stack на первом и третьем уровне, установить новые имена индексов и преобразовать их в столбцы:

df['date'] = pd.to_datetime(df['date'], format='%Y/%m/%d')

df = df.set_index('date')
df.columns = df.columns.str.split(':', expand=True)

df = df.stack([0,2]).rename_axis(['date','city','district']).reset_index()
print (df)
        date city district  quantity
0 2007-09-30   bj       dc   27.6901
1 2007-09-30   tj       hp   19.1000
2 2007-12-31   bj       dc   25.2259
3 2007-12-31   tj       hp   17.7000
4 2008-03-31   bj       dc   24.0400
5 2008-03-31   tj       hp   16.3000
6 2008-06-30   bj       dc   15.0000
7 2008-06-30   tj       hp   15.4000
8 2008-09-30   bj       dc    0.0000
9 2008-09-30   tj       hp   13.4000

Если вы хотите установить порядок сортировки столбцов, здесь MultiIndex:

df['date'] = pd.to_datetime(df['date'], format='%Y/%m/%d')

df = df.set_index('date')
df.columns = df.columns.str.split(':', expand=True)

df = df.stack([0,2]).sort_index(level=[1,2,0]).rename_axis(['date','city','district']).reset_index()
print (df)
        date city district  quantity
0 2007-09-30   bj       dc   27.6901
1 2007-12-31   bj       dc   25.2259
2 2008-03-31   bj       dc   24.0400
3 2008-06-30   bj       dc   15.0000
4 2008-09-30   bj       dc    0.0000
5 2007-09-30   tj       hp   19.1000
6 2007-12-31   tj       hp   17.7000
7 2008-03-31   tj       hp   16.3000
8 2008-06-30   tj       hp   15.4000
9 2008-09-30   tj       hp   13.4000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...