在给定键值数据帧的情况下填充密集数据帧



我有一个键值数据帧:

pd.DataFrame(columns=['X','Y','val'],data= [['a','z',5],['b','g',3],['b','y',6],['e','r',9]])
>    X Y val
   0 a z   5
   1 b g   3
   2 b y   6
   3 e r   9

我想将其转换为更密集的数据帧:

     X z g y r
   0 a 5 0 0 0
   1 b 0 3 6 0
   2 e 0 0 0 9

在我求助于纯蟒蛇之前,我想知道是否有一种简单的方法可以对熊猫做到这一点。

您可以使用

get_dummies:

In [11]: dummies = pd.get_dummies(df['Y'])
In [12]: dummies
Out[12]: 
   g  r  y  z
0  0  0  0  1
1  1  0  0  0
2  0  0  1  0
3  0  1  0  0

然后乘以 val 列:

In [13]: res = dummies.mul(df['val'], axis=0)
In [14]: res
Out[14]: 
   g  r  y  z
0  0  0  0  5
1  3  0  0  0
2  0  0  6  0
3  0  9  0  0

要修复索引,您只需将 X 添加为此索引,您可以先应用 set_index:

In [21]: df1 = df.set_index('X', append=True)
In [22]: df1
Out[22]: 
     Y  val
  X        
0 a  z    5
1 b  g    3
2 b  y    6
3 e  r    9
In [23]: dummies = pd.get_dummies(df['Y'])
In [24]: dummies.mul(df['val'], axis=0)
Out[24]: 
     g  r  y  z
  X            
0 a  0  0  0  5
1 b  3  0  0  0
2 b  0  0  6  0
3 e  0  9  0  0

如果要执行此透视(也可以使用 pivot_table):

In [31]: df.pivot('X', 'Y').fillna(0)
Out[31]: 
   val         
Y    g  r  y  z
X              
a    0  0  0  5
b    3  0  6  0
e    0  9  0  0

也许你想reset_index,让 X 成为一列(我不确定是否有意义):

In [32]: df.pivot('X', 'Y').fillna(0).reset_index()
Out[32]: 
   X  val         
Y       g  r  y  z
0  a    0  0  0  5
1  b    3  0  6  0
2  e    0  9  0  0

为完整起见,pivot_table:

In [33]: df.pivot_table('val', 'X', 'Y', fill_value=0)
Out[33]: 
Y  g  r  y  z
X            
a  0  0  0  5
b  3  0  6  0
e  0  9  0  0
In [34]: df.pivot_table('val', 'X', 'Y', fill_value=0).reset_index()
Out[34]: 
Y  X  g  r  y  z
0  a  0  0  0  5
1  b  3  0  6  0
2  e  0  9  0  0

注意:在重置索引后,列名被命名为Y,不确定这是否有意义(并且很容易通过res.columns.name = None纠正)。

如果你想要更直接的东西。类似于DataFrame.lookup但对于np.put来说可能是有意义的。

def lookup_index(self, row_labels, col_labels):
    values = self.values
    ridx = self.index.get_indexer(row_labels)
    cidx = self.columns.get_indexer(col_labels)
    if (ridx == -1).any():
        raise ValueError('One or more row labels was not found')
    if (cidx == -1).any():
        raise ValueError('One or more column labels was not found')
    flat_index = ridx * len(self.columns) + cidx
    return flat_index
flat_index = lookup_index(df, vals.X, vals.Y)
np.put(df.values, flat_index, vals.val.values)

这假定df具有适当的列和索引来保存 X/Y 值。这是一个 ipython 笔记本 http://nbviewer.ipython.org/6454120

最新更新