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
我有这样的数据:
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