包含重复索引的两个以上DataFrame的笛卡尔积

时间:2013-12-06 12:29:35

标签: python pandas

假设我有以下DataFrame,其中每一行代表特定用户在特定时间执行的事件:

In [1]: df
Out[1]: 
      time event
user            
a        1     x
a        2     y
a        3     z
b        1     x
b        2     x
b        3     z
b        4     z
c        1     y
c        2     y
c        3     z
d        1     z

我想重塑它,使其具有以下结构:

In [2]: dfm
Out[2]: 
       x   y  z
user           
a      1   2  3
b      1 NaN  3
b      1 NaN  4
b      2 NaN  3
b      2 NaN  4
c    NaN   1  3
c    NaN   2  3
d    NaN NaN  1

我目前通过首先为每个事件创建一个DataFrame来获得此结果:

In [3]: dfs = [d[['time']].rename(columns={'time': k}) for k, d in df.groupby('event')]

In [4]: dfs
Out[4]: 
[      x
 user   
 a     1
 b     1
 b     2,       y
 user   
 a     2
 c     1
 c     2,       z
 user   
 a     3
 b     3
 b     4
 c     3
 d     1]

然后多次调用pd.merge

In [5]: dfm = dfs[0]

In [5]: for d in dfs[1:]:
   ...:     dfm = pd.merge(dfm, d, left_index=True, right_index=True, how='outer')

这很好用,但我想知道是否有更好的方法。这不是大熊猫第一次以一些漂亮的功能让我感到惊讶!我尝试了pd.concat(dfs, axis=1),但是产生了以下错误(仅显示了最后一行):

ValueError: Shape of passed values is (1, 5), indices imply (1, 4)

我也查看了pd.pivot_table,但每个用户生成一行并平均时间戳。也许我忽略了一些东西。非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

以下是问题中讨论的解决方案

import pandas as pd
from StringIO import StringIO

data = \
'user,time,event\n\
a,1,x\n\
a,2,y\n\
a,3,z\n\
b,1,x\n\
b,2,x\n\
b,3,z\n\
b,4,z\n\
c,1,y\n\
c,2,y\n\
c,3,z\n\
d,1,z\n'

df = pd.read_csv(StringIO(data), index_col='user')
dfs = [d[['time']].rename(columns={'time': k}) for k, d in df.groupby('event')]
dfm = dfs[0]
for d in dfs[1:]:
    dfm = pd.merge(dfm, d, left_index=True, right_index=True, how='outer')