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

时间:2013-09-05 17:25:18

标签: pandas

我有一个键值数据框:

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

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

2 个答案:

答案 0 :(得分:3)

您可以使用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

然后multiply由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(你也可以使用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纠正)。

答案 1 :(得分:1)

如果你想要更直接的东西。类似于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