Как изменить форму данных с помощью wide_to_long или pivot? - PullRequest
2 голосов
/ 24 сентября 2019

Это должно быть довольно просто, но я не смог обернуть вокруг него мой мозг.

Я пытаюсь преобразовать df1 в df2, где df1 и df2 - кадры данных панд

df1 = pd.DataFrame({'site': ['1', '2'],
                    'sat_open': ['0900', '0900'],
                    'sat_close': ['1900','1900'],
                    'sun_open': ['1000', '1000'],
                    'sun_close': ['1800', '1800'],
                    'mon_open': ['0900', '0900'],
                    'mon_close': ['2100', '2100']               
                  })

df2 = pd.DataFrame({'store': ['1', '1', '1', '2', '2','2'],
                    'day': ['sat', 'sun', 'mon','sat', 'sun', 'mon'],
                    'open': ['09:00','10:00','09:00','09:00','10:00','09:00'],
                    'close': ['19:00','18:00','21:00','19:00','18:00','21:00']})

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

Ответы [ 2 ]

2 голосов
/ 24 сентября 2019

Вы можете сначала переключить имена столбцов, разделив их на _, а затем использовать pd.wide_to_long:

df1.columns = [f'{col.split("_")[1]}_{col.split("_")[0]}' if '_' in col else col 
               for col in df1.columns]

df2 = pd.wide_to_long(df1, stubnames=['open', 'close'], i='site', j='day', sep='_', suffix='\D+')\
        .sort_index(level=0)\
        .reset_index()

Выход

  site  day  open close
0    1  mon  0900  2100
1    1  sat  0900  1900
2    1  sun  1000  1800
3    2  mon  0900  2100
4    2  sat  0900  1900
5    2  sun  1000  1800
1 голос
/ 24 сентября 2019

Вы можете попробовать:

(pd.wide_to_long(df1, 
                 stubnames=['sat', 'sun','mon'], 
                 i='site', 
                 j='day', 
                 sep='_', suffix='(open|close)'
                )
   .stack()
   .unstack('day')
)

Вывод:

day      close  open
site                
1    sat  1900  0900
     sun  1800  1000
     mon  2100  0900
2    sat  1900  0900
     sun  1800  1000
     mon  2100  0900
...