重塑 pandas 数据框 stack/unstack
Re-shape pandas dataframe stack/unstack
df = pd.DataFrame({'BORDER':['GERMANY','FRANCE','ITALY','USA','CANADA','MEXICO','INDIA','CHINA','JAPAN' ], 'ASID':[21, 32, 99, 77,66,55,44,88,111], 'HOUR1':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6],'HOUR2':[3 ,3 ,3, 5 ,5 ,5, 7, 7, 7], 'HOUR3':[8 ,8 ,8, 12 ,12 ,12, 99, 99, 99], 'PRICE1':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6], 'PRICE2':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6],'PRICE3':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6] })
df = df[['ASID', 'BORDER', 'HOUR1', 'PRICE1', 'HOUR2', 'PRICE2', 'HOUR3', 'PRICE3']]
过去一天我一直在尝试重塑这个数据框。修补 stack/unstack/melt 并将列转换为索引等,但未能实现我的目标。
所需的输出具有以下列:
ASID, BORDER, HOUR, PRICE
我想将所有 ['HOUR1', 'HOUR2', HOUR3']
堆叠成一个 column = HOUR
。
同样,我想将所有 ['PRICE1', 'PRICE2', 'PRICE3']
堆叠在一个 column = PRICE
中,以便此字段中的值与 HOUR
列中的相应值对齐。 HOUR1
& PRICE1
、HOUR2
& PRICE2
、HOUR3
& PRICE3
、
之间有一个link
非常感谢您提供的任何指导。
原始数据(注意更正第二行的 'PRICE1')。
df = pd.DataFrame({'BORDER':['GERMANY','FRANCE','ITALY','USA','CANADA','MEXICO','INDIA','CHINA','JAPAN' ], 'ASID':[21, 32, 99, 77,66,55,44,88,111], 'HOUR1':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6],'HOUR2':[3 ,3 ,3, 5 ,5 ,5, 7, 7, 7], 'HOUR3':[8 ,8 ,8, 12 ,12 ,12, 99, 99, 99], 'PRICE1':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6], 'PRICE2':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6],'PRICE3':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6] })
df = df[['ASID', 'BORDER', 'HOUR1', 'PRICE1', 'HOUR2', 'PRICE2', 'HOUR3', 'PRICE3']]
首先,将索引设置为ASID
和BORDER
。
df.set_index(['ASID', 'BORDER'], inplace=True)
然后,为价格和时间创建两个 DataFrame,堆叠结果。从这些堆叠的 DataFrame 中删除小时数和价格水平。
prices = df[['PRICE1','PRICE2', 'PRICE3']].stack()
prices.index = prices.index.droplevel(2)
hours = df[['HOUR1', 'HOUR2', 'HOUR3']].stack()
hours.index = hours.index.droplevel(2)
最后,连接这两个 DataFrame 并重命名您的列。
df_new = pd.concat([hours, prices], axis=1)
df_new.columns = ['HOUR', 'PRICE']
>>> df_new
HOUR PRICE
ASID BORDER
21 GERMANY 2 2
GERMANY 3 2
GERMANY 8 2
32 FRANCE 2 2
FRANCE 3 2
FRANCE 8 2
99 ITALY 2 2
ITALY 3 2
ITALY 8 2
77 USA 4 4
USA 5 4
USA 12 4
66 CANADA 4 4
CANADA 5 4
CANADA 12 4
55 MEXICO 4 4
MEXICO 5 4
MEXICO 12 4
44 INDIA 6 6
INDIA 7 6
INDIA 99 6
88 CHINA 6 6
CHINA 7 6
CHINA 99 6
111 JAPAN 6 6
JAPAN 7 6
JAPAN 99 6
df = pd.DataFrame({'BORDER':['GERMANY','FRANCE','ITALY','USA','CANADA','MEXICO','INDIA','CHINA','JAPAN' ], 'ASID':[21, 32, 99, 77,66,55,44,88,111], 'HOUR1':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6],'HOUR2':[3 ,3 ,3, 5 ,5 ,5, 7, 7, 7], 'HOUR3':[8 ,8 ,8, 12 ,12 ,12, 99, 99, 99], 'PRICE1':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6], 'PRICE2':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6],'PRICE3':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6] })
df = df[['ASID', 'BORDER', 'HOUR1', 'PRICE1', 'HOUR2', 'PRICE2', 'HOUR3', 'PRICE3']]
过去一天我一直在尝试重塑这个数据框。修补 stack/unstack/melt 并将列转换为索引等,但未能实现我的目标。
所需的输出具有以下列:
ASID, BORDER, HOUR, PRICE
我想将所有 ['HOUR1', 'HOUR2', HOUR3']
堆叠成一个 column = HOUR
。
同样,我想将所有 ['PRICE1', 'PRICE2', 'PRICE3']
堆叠在一个 column = PRICE
中,以便此字段中的值与 HOUR
列中的相应值对齐。 HOUR1
& PRICE1
、HOUR2
& PRICE2
、HOUR3
& PRICE3
、
非常感谢您提供的任何指导。
原始数据(注意更正第二行的 'PRICE1')。
df = pd.DataFrame({'BORDER':['GERMANY','FRANCE','ITALY','USA','CANADA','MEXICO','INDIA','CHINA','JAPAN' ], 'ASID':[21, 32, 99, 77,66,55,44,88,111], 'HOUR1':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6],'HOUR2':[3 ,3 ,3, 5 ,5 ,5, 7, 7, 7], 'HOUR3':[8 ,8 ,8, 12 ,12 ,12, 99, 99, 99], 'PRICE1':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6], 'PRICE2':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6],'PRICE3':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6] })
df = df[['ASID', 'BORDER', 'HOUR1', 'PRICE1', 'HOUR2', 'PRICE2', 'HOUR3', 'PRICE3']]
首先,将索引设置为ASID
和BORDER
。
df.set_index(['ASID', 'BORDER'], inplace=True)
然后,为价格和时间创建两个 DataFrame,堆叠结果。从这些堆叠的 DataFrame 中删除小时数和价格水平。
prices = df[['PRICE1','PRICE2', 'PRICE3']].stack()
prices.index = prices.index.droplevel(2)
hours = df[['HOUR1', 'HOUR2', 'HOUR3']].stack()
hours.index = hours.index.droplevel(2)
最后,连接这两个 DataFrame 并重命名您的列。
df_new = pd.concat([hours, prices], axis=1)
df_new.columns = ['HOUR', 'PRICE']
>>> df_new
HOUR PRICE
ASID BORDER
21 GERMANY 2 2
GERMANY 3 2
GERMANY 8 2
32 FRANCE 2 2
FRANCE 3 2
FRANCE 8 2
99 ITALY 2 2
ITALY 3 2
ITALY 8 2
77 USA 4 4
USA 5 4
USA 12 4
66 CANADA 4 4
CANADA 5 4
CANADA 12 4
55 MEXICO 4 4
MEXICO 5 4
MEXICO 12 4
44 INDIA 6 6
INDIA 7 6
INDIA 99 6
88 CHINA 6 6
CHINA 7 6
CHINA 99 6
111 JAPAN 6 6
JAPAN 7 6
JAPAN 99 6