Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用pandas melt将多列转换为行_Python_Pandas - Fatal编程技术网

Python 如何使用pandas melt将多列转换为行

Python 如何使用pandas melt将多列转换为行,python,pandas,Python,Pandas,我在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

我在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
我正在使用pandas将其转换为另一个具有以下结构的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
我之前在pandas中使用了melt函数将一列转换为行(例如sales或Units),我不知道它是否适用于三个多索引列

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变量(SKU、单位和销售额)

Idea是由第一列创建的索引,由前两行创建的多索引,因此可能使用:

如果excel文件中缺少第二个值,则需要预处理:

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
编辑1:

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  
如果需要仅过滤某些列以进行重塑:

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
编辑1:

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  


与…相反

我不知道它是否适用于三个或多个索引列

是的,它适用于多索引列。如果列是多索引,则使用
col\u level
参数进行熔化。
示例在第一个链接中提供。

只是为了添加,如果我有更多的日期值,我是否应该将所有数据都插入到多索引中,如多索引(级别=['SKU'、'Sales'、'Units']、['11/5/18'、'12/5/18',13/5/18,14/518……]还是有什么alternative@Tejas-是的,当然。这里的主要问题是从前两行创建
multi-index
,我的解决方案有效吗?返回什么
print(df.columns)
在您的数据中?您好,我尝试运行,但遇到错误,在指定多索引标题时无法指定usecols,如何排除故障this@Tejas-数据是否机密?因为如果机密数据只需要第一行数据和标题,没有yoyur excel就很难解决您的问题(可以自由更改一些示例的值,如
aaa
bbb
)我的excel数据与我问题中第一个表的数据相同
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
#reshape and rename columns names
d = {'level_0':'a','level_1':'dates','level_2':'b'}
df = df.unstack().reset_index(name='vals').rename(columns=d)
print (df)
        a    dates         b  Desc  vals
0    SKU   11/5/18               0     1
1    SKU   11/5/18               0     1
2    SKU   12/5/18               0     2
3    SKU   12/5/18               0     2
4   Units  11/5/18   total=9     0     3
5   Units  11/5/18   total=9     0     3
6   Units  12/5/18   total=5     0     4
7   Units  12/5/18   total=5     0     4
8   Sales  11/5/18  total=33     0     5
9   Sales  11/5/18  total=33     0     5
10  Sales  12/5/18  total=60     0     6
11  Sales  12/5/18  total=60     0     6