Pivot_table in pandas 具有 rowid 序列

Pivot_table in pandas with a rowid sequence

我有这样的数据:

ID        Cue       trial     time     accuracy
A         apple     copy      1450     1 
A         dog       copy      2154     1
A         apple     test1     2121     0
A         dog       test2     0        1
A         apple     final     1231     0
A         dog       final     5411     1
B         apple     copy      818      0
B         ...       ...       ..      ...

我需要对其进行转换,以便每个 ID 和 Cue 组合都在一行上:

  A       apple   apple    apple   copy  test1   final   1450  2121  1231  1   0   0
  ...

在 R 中,我可以通过 data.table 使用 dcast 轻松做到这一点:

 dcast(data, ID + Cue ~ rowid(ID, Cue), value.var=c("time", "accuracy"))

但是在Pandas我遇到了麻烦。如果我使用 pivot_table,结果不正确。例如,如果我这样做:

 data.pivot_table(index=['ID', 'Cue', 'TrialType'], values=['time', 'accuracy'])

结果总是这样:

 A      apple     copy     1450    1
                  final    1231    0
                  test1    2121    0

问题是我需要不堆叠 "trial" 列,但 pivot_table / crosstab 似乎无法处理这个问题。请注意,如果我将 "columns='trial'" 放在 pivot_table 中,它将无法满足我的目的,因为 'trial' 列在我的分析中用作分类变量。

如有任何提示,我们将不胜感激。

将列 Cue 复制到新的 Cue1 以获取第二个位置 DataFrame.insert, unpivot by DataFrame.melt, add counter by GroupBy.cumcount and reshape by DataFrame.set_index with Series.unstack:

df.insert(1, 'Cue1', df['Cue'])
df = df.melt(['ID','Cue'])
df['g'] = df.groupby(['ID','Cue']).cumcount()
df = df.set_index(['ID', 'Cue', 'g'])['value'].unstack().reset_index(level=1, drop=True)
print (df)

g      0      1      2     3      4      5     6     7     8    9    10   11
ID                                                                          
A   apple  apple  apple  copy  test1  final  1450  2121  1231    1    0    0
A     dog    dog    dog  copy  test2  final  2154     0  5411    1    1    1
B   apple   copy    818     0    NaN    NaN   NaN   NaN   NaN  NaN  NaN  NaN

另一个想法:

c = df.columns.difference(['ID'], sort=False)
df = (df.groupby(['ID','Cue'])[c]
        .apply(lambda x: pd.DataFrame([x.T.values.ravel()]))
        .reset_index(level=[1,2], drop=True))
print (df)
        0      1      2     3      4      5       6       7       8    9   10  \
ID                                                                              
A   apple  apple  apple  copy  test1  final  1450.0  2121.0  1231.0  1.0  0.0   
A     dog    dog    dog  copy  test2  final  2154.0     0.0  5411.0  1.0  1.0   
B   apple   copy    818     0    NaN    NaN     NaN     NaN     NaN  NaN  NaN   

     11  
ID       
A   0.0  
A   1.0  
B   NaN