【发布时间】:2014-05-05 01:34:33
【问题描述】:
假设我有以下 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')
这很好用,但我想知道是否有更好的方法。 pandas 的一些漂亮功能让我感到惊讶,这已经不是第一次了!我试过pd.concat(dfs, axis=1),但会产生以下错误(仅显示最后一行):
ValueError: Shape of passed values is (1, 5), indices imply (1, 4)
我还研究了pd.pivot_table,但这会为每个用户生成一行并平均时间戳。也许我忽略了一些东西。非常感谢任何帮助!
【问题讨论】:
-
你应该可以使用pivot来完成你想要的
-
我尝试了
pd.pivot_table的各种咒语,但无济于事。你能分享正确的吗? -
看起来您的解决方案是最好的解决方案。枢轴对您的情况很有帮助。