我在excel中有如下数据集
A B C D E F G
1 SKU Units Sales
2 11/5/18 12/5/18 11/5/18 12/5/18 11/5/18 12/5/18
3 Description total=5 total=9 total=33 total =60
4 Nail Varnish 2345 2345 2 4 $15 $30
5 Eyeliner 2346 2345 3 5 $18 $30
我正在使用熊猫将其转换为具有以下结构的另一个excel
Description date sku Units Sales
0 Nail Varnish 11/5/18 2345 2 $15
1 Eye liner 11/5/18 2346 3 $18
2 Nail Varnish 12/5/18 2345 4 $30
3 Eye liner 12/5/18 2346 5 $30
我之前在熊猫中使用过melt函数将一列转换为行(例如,销售或单位),但我不知道它是否适用于三个多索引列。
df = pd.read_excel(filepath_name,index_col=False,usecols="A:G")
df2=pd.melt(df,id_vars=["SKU ","Units","Sales"], var_name ="Date", value_name='?)
但是我该如何一次性转换所有id vars(SKU,Units和Sales)。
答案 0 :(得分:2)
创建的想法的索引是第一列,而MultiIndex的索引是前2行,因此可以使用DataFrame.stack
:
.as-console-wrapper { max-height: 100% !important; top: auto; }
如果excel文件中缺少第二个值,则需要进行预处理:
df = pd.read_excel(filepath_name,index_col=[0],usecols="A:G", header=[0,1])
print (df.columns)
MultiIndex(levels=[['SKU', 'Sales', 'Units'], ['11/5/18', '12/5/18']],
codes=[[0, 0, 2, 2, 1, 1], [0, 1, 0, 1, 0, 1]])
df = df.stack().rename_axis(('Description','date')).reset_index()
print (df)
Description date SKU Sales Units
0 Nail Varnish 11/5/18 2345 $15 2
1 Nail Varnish 12/5/18 2345 $30 4
2 Eyeliner 11/5/18 2346 $18 3
3 Eyeliner 12/5/18 2345 $30 5
EDIT1:
如果只需要过滤某些列以进行重塑:
print (df)
SKU Unnamed: 1_level_0 Units Unnamed: 3_level_0 Sales \
11/5/18 12/5/18 11/5/18 12/5/18 11/5/18
Nail Varnish 2345 2345 2 4 $15
Eyeliner 2346 2345 3 5 $18
Unnamed: 5_level_0
12/5/18
Nail Varnish $30
Eyeliner $30
a = df.columns.get_level_values(0)
b = df.columns.get_level_values(1)
a = a.where(~a.str.startswith('Unnamed')).to_series().ffill()
df.columns = [a, b]
print (df)
SKU Units Sales
11/5/18 12/5/18 11/5/18 12/5/18 11/5/18 12/5/18
Nail Varnish 2345 2345 2 4 $15 $30
Eyeliner 2346 2345 3 5 $18 $30
EDIT1:
cols = ['SKU','Units','Sales']
df = df[cols].stack().rename_axis(('Description','date')).reset_index()
print (df)
Description date SKU Sales Units
0 Nail Varnish 11/5/18 2345 $15 2
1 Nail Varnish 12/5/18 2345 $30 4
2 Eyeliner 11/5/18 2346 $18 3
3 Eyeliner 12/5/18 2345 $30 5
mux = pd.MultiIndex(levels=[['SKU ', 'Units', 'Unnamed: 0_level_0', 'Sales'],
['11/5/18', '12/5/18', 'Unnamed: 0_level_1'],
['total=5', 'total=9', 'total=33', 'total=60', 'Description', 'Unnamed: 1_level_2', 'Unnamed: 2_level_2']], codes=[[2, 0, 0, 1, 1, 3, 3], [2, 0, 1, 0, 1, 0, 1], [4, 5, 6, 1, 0, 2, 3]])
df = pd.DataFrame([range(7),range(7)], columns=mux)
print (df)
Unnamed: 0_level_0 SKU Units \
Unnamed: 0_level_1 11/5/18 12/5/18 11/5/18 12/5/18
Description Unnamed: 1_level_2 Unnamed: 2_level_2 total=9 total=5
0 0 1 2 3 4
1 0 1 2 3 4
Sales
11/5/18 12/5/18
total=33 total=60
0 5 6
1 5 6
a = df.columns.get_level_values(0)
b = df.columns.get_level_values(1)
c = df.columns.get_level_values(2)
#forward fliing missing values
a = a.where(~a.str.startswith('Unnamed')).to_series().ffill()
b = b.where(~b.str.startswith('Unnamed')).to_series().ffill()
#repalce missing values by empty string
c = c.where(~c.str.startswith('Unnamed'), '')
df.columns = [a, b, c]
#convert first column to index
df = df.set_index(df.columns[0])
df.index.name='Desc'
print (df)
SKU Units Sales
11/5/18 12/5/18 11/5/18 12/5/18 11/5/18 12/5/18
total=9 total=5 total=33 total=60
Desc
0 1 2 3 4 5 6
0 1 2 3 4 5 6
答案 1 :(得分:0)
information与melt
相反。
而且我不知道它是否适用于三个或多个索引列。
是的,它适用于多索引列。如果列是MultiIndex,则使用col_level
参数进行融化。
第一个链接中提供了示例。