首页 > 解决方案 > 使用 pandas 重塑交易订单的数据集

问题描述

我有一个用于交易头寸的数据集,其中每个订单显示在 2 行中,分别是卖出/买入行和平仓行:(在下面的示例中,订单 #1sell位于第 0 行和close第 6 行)

        order time order type  order N.  order size  order price  order profit  balance
0  2020.11.04 00:00      sell        1        0.01      1.17128           NaN      NaN
1  2020.11.04 00:10       buy        2        0.01      1.17125           NaN      NaN
2  2020.11.04 00:45     close        2        0.01      1.17232           1.0    201.0
3  2020.11.04 01:03      sell        3        0.02      1.17328           NaN      NaN
4  2020.11.04 01:31      sell        4        0.02      1.17528           NaN      NaN
6  2020.11.04 02:38     close        1        0.01      1.17261          -1.4    199.6
7  2020.11.04 02:38     close        3        0.02      1.17261           1.2    200.8
8  2020.11.04 02:38     close        4        0.02      1.17261           5.2    206.0

我想重塑,使每个订单成为一个单独的行而不是 2 行:

#desired output:

order N.  buy/sell_time        close_time         order_size    order_type     order_profit   balance
1         2020.11.04 00:00     2020.11.04 02:38   0.01          sell           -1.4           199.6
2         2020.11.04 00:10     2020.11.04 00:45   0.01          buy            1.0            201.0
3         2020.11.04 01:03     2020.11.04 02:38   0.02          sell           1.2            200.8
4         2020.11.04 01:31     2020.11.04 02:38   0.02          sell           5.2            206.0

我尝试了这段代码但没有成功:

df.melt(id_vars=['order #'])

编辑

一些订单号有超过 2 个条目

标签: pythonpandas

解决方案


如果您不想像@Chris 建议的那样拆分数据,您需要事先和之后进行一些数据处理,以便能够旋转并获得您指定的输出:

In [40]: df['order type'] = df['order type'].replace({'buy': 'buy / sell', 'sell' : 'buy / sell'}) 

In [86]: df                                                                                                                                                                                                        
Out[86]: 
         order time  order type  order N.  order size  order price  order profit  balance
0  2020.11.04 00:00  buy / sell         1        0.01       1.1713           NaN      NaN
1  2020.11.04 00:10  buy / sell         2        0.01       1.1712           NaN      NaN
2  2020.11.04 00:45       close         2        0.01       1.1723           1.0    201.0
3  2020.11.04 01:03  buy / sell         3        0.02       1.1733           NaN      NaN
4  2020.11.04 01:31  buy / sell         4        0.02       1.1753           NaN      NaN
6  2020.11.04 02:38       close         1        0.01       1.1726          -1.4    199.6
7  2020.11.04 02:38       close         3        0.02       1.1726           1.2    200.8
8  2020.11.04 02:38       close         4        0.02       1.1726           5.2    206.0

有了这个准备,你可以转动:

In [75]: df2 = df.pivot(index='order N.', columns='order type', values=['order time', 'order size', 'order profit', 'balance']).dropna(axis=1)                                                                           
Out[75]: 
                  order time                   order size       order profit balance
order type        buy / sell             close buy / sell close        close   close
order N.                                                                            
1           2020.11.04 00:00  2020.11.04 02:38       0.01  0.01         -1.4   199.6
2           2020.11.04 00:10  2020.11.04 00:45       0.01  0.01            1     201
3           2020.11.04 01:03  2020.11.04 02:38       0.02  0.02          1.2   200.8
4           2020.11.04 01:31  2020.11.04 02:38       0.02  0.02          5.2     206

这使得“订单 N”。您的新索引意味着您每“订单 N.”获得一行。新列是“订单类型”的值,意思是“买/卖”或“平仓”。'买/卖'没有'订单利润'或'余额',所以这些被丢弃dropna

输出标签仍然有点多余,因为pivot创建了一个仅在“订单时间”需要的多索引。这可以美化

In [82]: df2.columns = [t[0] if t[0] != 'order time' else ' '.join(t) for t in df2.columns.to_flat_index()]

In [85]: df2                                                                                                                                                                                                       
Out[85]: 
         order time buy / sell  order time close order size order size order profit balance
order N.                                                                                   
1             2020.11.04 00:00  2020.11.04 02:38       0.01       0.01         -1.4   199.6
2             2020.11.04 00:10  2020.11.04 00:45       0.01       0.01            1     201
3             2020.11.04 01:03  2020.11.04 02:38       0.02       0.02          1.2   200.8
4             2020.11.04 01:31  2020.11.04 02:38       0.02       0.02          5.2     206

最后将重复数据删除到“订单大小”列,这是多余的

In [89]: df2.loc[:, ~df2.columns.duplicated()]                                                                                                                                                                     
Out[89]: 
         order time buy / sell  order time close order size order profit balance
order N.                                                                        
1             2020.11.04 00:00  2020.11.04 02:38       0.01         -1.4   199.6
2             2020.11.04 00:10  2020.11.04 00:45       0.01            1     201
3             2020.11.04 01:03  2020.11.04 02:38       0.02          1.2   200.8
4             2020.11.04 01:31  2020.11.04 02:38       0.02          5.2     206

然而,对于两种订单类型,这可能是矫枉过正


推荐阅读