1

我有一个键值数据框:

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

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

4

2 回答 2

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

然后乘以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)。

于 2013-09-05T17:50:25.720 回答
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

于 2013-09-05T18:52:40.427 回答