Unpivot/Flatten pandas 将 table 转换为一级索引

Unpivot/Flatten pandas pivot table into one level index

为了进行分析,我从一个数据框开始,它看起来像这样(但要大得多):

      ID1        ID2           type       Number
0     IE345      E90              I           38
1     IE345      E92              E           26
2     IE345      E93              E           21
3     IE345      E95              R            9
4     IE346      E94              I           41
7     IE346      BLK              E            1

我想取消透视以下数据框:

Df1 = pd.pivot_table(loads, values=['Number'], 
                       index = ['ID1', 'ID2'], 
                       columns=['Type'], margins=True, 
                       aggfunc=[sum] , fill_value=0)

Df1:

                               sum                                                    
                       Number                                                             
type                             B     D     E     I    L     R    All                         
ID1        ID2                                                                         
IE345      E90                   0     0     0    38    0     0     38    
           E92                   0     0    26     0    0     0     26    
           E93                   0     0    21     0    0     0     21    
           E95                   0     0     0     0    0     9      9    
IE346      E94                   0     0     0    41    0     0     41    
           BLK                   0     0     1     0    0     0      1  

进入:

Df1:

ID1        ID2                   B     D     E     I    L     R    All                                                                         
IE345      E90                   0     0     0    38    0     0     38    
IE345      E92                   0     0    26     0    0     0     26    
IE345      E93                   0     0    21     0    0     0     21    
IE345      E95                   0     0     0     0    0     9      9    
IE346      E94                   0     0     0    41    0     0     41    
IE346      BLK                   0     0     1     0    0     0      1

似乎 pandas.melt 是我要找的东西,但无法让它发挥作用。

然后我想添加一行中最高值的列名,但当然没有边距:

ID1        ID2                   B     D     E     I    L     R    All   Max                                                                        
IE345      E90                   0     0     0    38    0     0     38    I    
IE345      E92                   0     0    26     0    0     0     26    E
IE345      E93                   0     0    21     0    6     0     27    E
IE345      E95                   0     0     0     0    0     9      9    R
IE345      E94                   0     0     0    41    0     0     41    I
IE345      BLK                   0     0     1     0    1     0      2    E

对于最大值,我使用了:

df['Max'] = df.idxmax(axis=1, skipna=True)

但不幸的是,这需要全部。关于如何以最有效的方式实现我的目标有什么想法吗?

!!!编辑!!!!

对于第一部分,我构建了一个解决方案,该解决方案 returns 确定了一个逆轴 table!看这里的代码:

df.columns = df.columns.get_level_values('Type')
df.reset_index(inplace=True)

现在我尝试了 Vmg 的解决方案,但不幸的是 returns:

ValueError: could not convert string to float: 

关于如何解决这个问题有什么想法吗?

您描述的第一个转换似乎没有必要,因为您似乎仍然希望 ID1ID2 成为索引。第一种表示方式 pandas 显示多个索引,而无需为第二个条目中的每个条目重复第一个索引。

你手头的问题,应用 idxmax 没有全部可以通过以下方式实现:

proef['Dominant'] = proef.iloc[:,:-1].idxmax(axis=1, skipna=True)

其中 iloc[:,:-1] 仅表示您忽略了最右边的列。

正如@vmg 已经说过的,idxmax 会成功:

import io
import StringIO     # for Python 2.X
import pandas as pd

data = """\
      id1        id2           type       number
0     IE345      E90              I           38
1     IE345      E92              E           26
2     IE345      E93              E           21
3     IE345      E95              R            9
4     IE346      E94              I           41
7     IE346      BLK              E            1
"""

#loads = pd.read_csv(io.StringIO(data), sep='\s+', index_col=0)  # for Python 3.X
loads = pd.read_csv(StringIO.StringIO(data), sep='\s+', index_col=0)  # for Python 2.X

# **** interesting part starts here ****

# save all unique types, we will use it later
types = loads.type.unique()

df = pd.pivot_table(loads, values=['number'], 
                       index = ['id1', 'id2'], 
                       columns=['type'], margins=True, 
                       aggfunc='sum', fill_value=0) \
       .reset_index()

# reset column names
df.columns = [c[1] if c[1] else c[0] for c in df.columns.tolist()]

df['max'] = df[types].idxmax(axis=1)

输出:

In [266]: df
Out[266]:
     id1  id2     E     I    R    All max
0  IE345  E90   0.0  38.0  0.0   38.0   I
1  IE345  E92  26.0   0.0  0.0   26.0   E
2  IE345  E93  21.0   0.0  0.0   21.0   E
3  IE345  E95   0.0   0.0  9.0    9.0   R
4  IE346  BLK   1.0   0.0  0.0    1.0   E
5  IE346  E94   0.0  41.0  0.0   41.0   I
6    All       48.0  79.0  9.0  136.0   I