在 Pandas 中,如何将 "long" table 转换为 "wide and sparse" table?

In Pandas, how can I convert a "long" table to a "wide and sparse" table?

我的术语很糟糕,所以这个术语值得解释一下。想象一下,我有一个像这样的 DataFrame(我称之为 "long" table):

time       stock     price
---------------------------
13:03:00   AAPL      100.00
13:03:00   SPY       200.00
13:03:01   AAPL      100.01
13:03:02   SPY       200.01
13:03:03   SPY       200.02
.
.
.

我想将它转换成这样的 DataFrame(我称之为 "wide and sparse" table):

time       AAPL      SPY
---------------------------
13:03:00   100.00    200.00
13:03:01   100.01    Nan
13:03:02   Nan       200.01
13:03:03   Nan       200.02

很明显,这是一个很大的转变。是否有执行此操作的内置函数?看起来这可能是一件很常见的事情。

谢谢!

您可以使用 pivot:

df = df.pivot(index='time', columns='stock', values='price')
print (df)
stock       AAPL     SPY
time                    
13:03:00  100.00  200.00
13:03:01  100.01     NaN
13:03:02     NaN  200.01
13:03:03     NaN  200.02

unstack的另一个解决方案:

df = df.set_index(['time', 'stock']).price.unstack()
print (df)
stock       AAPL     SPY
time                    
13:03:00  100.00  200.00
13:03:01  100.01     NaN
13:03:02     NaN  200.01
13:03:03     NaN  200.02

但是如果得到:

ValueError: Index contains duplicate entries, cannot reshape

是否需要使用 pivot_table 和一些聚合函数,默认 np.mean.

print (df)
       time stock   price
0  13:03:00  AAPL  100.00
1  13:03:00   SPY  200.00
2  13:03:01  AAPL  100.01
3  13:03:02   SPY  200.01
4  13:03:03   SPY  200.02
5  13:03:03   SPY  500.02 <- duplicates for same time and stock 


df = df.pivot_table(index='time', columns='stock', values='price')
print (df)
stock       AAPL     SPY
time                    
13:03:00  100.00  200.00
13:03:01  100.01     NaN
13:03:02     NaN  200.01
13:03:03     NaN  350.02

重复 timestock 的另一种可能解决方案:

df = df.groupby(['time', 'stock']).price.mean().unstack()
print (df)
stock       AAPL     SPY
time                    
13:03:00  100.00  200.00
13:03:01  100.01     NaN
13:03:02     NaN  200.01
13:03:03     NaN  350.02