熊猫在不同长度的列上合并两个数据框
Posted
技术标签:
【中文标题】熊猫在不同长度的列上合并两个数据框【英文标题】:Pandas merge two dataframes on column with different length 【发布时间】:2021-04-27 09:37:08 【问题描述】:我正在研究交易算法,但在尝试将 buy_orders 和 sell_orders 数据帧组合到单个数据帧订单时遇到了一些问题。
问题在 2021 年 1 月 21 日的buy_order 日期显示,我的算法建议购买,但由于尚未发现信号,因此还没有卖出订单,因此这些应该是 NAN合并时。 如果我要加入索引,则卖单将是与 sell_orders 数据框不同的股票的卖单。
buy_orders 数据框
Date_buy Name Stock_Price_buy Order
26 2020-07-30 AAPL 96.19 buy
27 2020-09-30 AAPL 115.81 buy
28 2020-11-05 AAPL 119.03 buy
29 2020-11-30 AAPL 119.05 buy
30 2021-01-21 AAPL 136.87 buy
31 2020-10-11 ABBV 21.21 buy
sell_orders 数据框
Date_sell Name Stock_Price_sell Order
25 2020-07-20 AAPL 98.36 sell
26 2020-09-02 AAPL 131.40 sell
27 2020-10-20 AAPL 117.51 sell
28 2020-11-20 AAPL 117.34 sell
29 2021-01-04 AAPL 129.41 sell
30 2020-10-15 ABBV 24.23 sell
理想的结果是如下所示的订单数据框。
Index Buy_date Name_x Stock_Price_buy Order_x Sell_date Name_y Stock_Price_buy Order_y
26 2020-07-30 AAPL 96.19 buy 2020-09-02 AAPL 131.40 sell
27 2020-09-30 AAPL 115.81 buy 2020-10-20 AAPL 117.51 sell
28 2020-11-05 AAPL 119.03 buy 2020-11-20 AAPL 117.34 sell
29 2020-11-30 AAPL 119.05 buy 2021-01-04 AAPL 129.41 sell
30 2021-01-21 AAPL 136.87 buy NaN NaN NaN NaN
当 buy_orders.Name_x 和 sell_orders.Name_y 第一次不同时,订单数据框现在的样子如下。 ABBV sell_order 应该是 NANs
28 2020-11-05 AAPL 119.03 buy 2020-11-20 AAPL 117.34 sell
29 2020-11-30 AAPL 119.05 buy 2021-01-04 AAPL 129.41 sell
30 2021-01-21 AAPL 136.87 buy 2018-05-24 ABBV 24.23 sell
【问题讨论】:
我正在考虑在合并时使用一个条件,例如 if buy_orders.Date > sell_orders.Date 在所有列中插入 NAN。 【参考方案1】:你有没有想过加入但随后声明后缀如下?
buy_orders.join(sell_orders,lsuffix='_buy', rsuffix='_sell')
Date_buy Name_buy Stock_Price_buy Order_buy Date_sell Name_sell \
26 2020-07-30 AAPL 96.19 buy 2020-09-02 AAPL
27 2020-09-30 AAPL 115.81 buy 2020-10-20 AAPL
28 2020-11-05 AAPL 119.03 buy 2020-11-20 AAPL
29 2020-11-30 AAPL 119.05 buy 2021-01-04 AAPL
30 2021-01-21 AAPL 136.87 buy NaN NaN
Stock_Price_sell Order_sell
26 131.40 sell
27 117.51 sell
28 117.34 sell
29 129.41 sell
30 NaN NaN
【讨论】:
添加了我的输出的样子。正如所观察到的,ABBV sell_order 应该是 NANs 您的示例数据中的the ABBV sell_order
在哪里?
我认为没有必要,但它被添加了。
你的意思是buy_orders.merge(sell_orders, how='left',on='Name',left_index=True, right_index=True, suffixes=('_x', '_y'))
?
很抱歉,这并没有返回我原始帖子中显示的所需数据帧:(【参考方案2】:
假设您的数据是结构化的,它始终以买单开始并与卖单交替,并且每天只有一笔交易,并且每笔交易始终是一个大小的手数...您可以使用pd.concat
。我制作了一个类似于您的简单数据框(将来,如果您在问题中包含用于制作示例数据框的代码,它会变得更容易):
buy_orders = pd.DataFrame.from_dict('Date_buy': [ pd.to_datetime('2020-11-01'), pd.to_datetime('2020-11-03'),
pd.to_datetime('2020-11-05'), pd.to_datetime('2020-11-08'),
pd.to_datetime('2020-11-10')],
'Order' : ['B','B','B','B','B'],
'Name' : ['AAPL','AAPL','AAPL','AAPL','ABBV'],
'Stock_Price_buy' : [1,2,3,4,5.0])
sell_orders = pd.DataFrame.from_dict('Date_sell': [ pd.to_datetime('2020-11-02'), pd.to_datetime('2020-11-04'),
pd.to_datetime('2020-11-06'), pd.to_datetime('2020-11-12'),
pd.to_datetime('2020-11-22')],
'Order' : ['S','S','S','S','S'],
'Name' : ['AAPL','AAPL','AAPL','ABBV','ABBV'],
'Stock_Price_sell' : [23,24,25,26,5.0])
您可以先将两个数据框堆叠起来,然后按日期和代码对其进行排序(在规范化列名之后):
buy_orders = buy_orders.rename(columns='Date_buy' : "Date", "Stock_Price_buy" : "Price")
sell_orders = sell_orders.rename(columns='Date_sell' : "Date", "Stock_Price_sell" : "Price")
df = pd.concat([buy_orders, sell_orders])
df = df.sort_values(['Date','Order']).reset_index(drop=True)
...然后制作数据帧的副本(更改列名以在后面的连接步骤中保持它们的区别):
df2 = df.copy()
df2.columns = [f"c_sell" for c in df.columns]
然后,您将两个数据帧彼此相邻连接,但在第二个数据帧上使用 .shift(-1)
以便它们偏移
df3 = pd.concat([df, df2.shift(-1)], axis=1)
最后,你可以清理垃圾行了:
cut = ( df3.Name != df3.Name_sell)
import numpy as np
df3.loc[cut, 'Date_sell'] = np.nan
df3.loc[cut, 'Order_sell'] = np.nan
df3.loc[cut, 'Price_sell'] = np.nan
df3 = df3.drop(columns='Name_sell')
df3 = df3[df3.Order!="S"].reset_index(drop=True).copy()
这给了你类似的东西
Date Order Name Price Date_sell Order_sell Price_sell
0 2020-11-01 B AAPL 1.0 2020-11-02 S 23.0
1 2020-11-03 B AAPL 2.0 2020-11-04 S 24.0
2 2020-11-05 B AAPL 3.0 2020-11-06 S 25.0
3 2020-11-08 B AAPL 4.0 NaT NaN NaN
4 2020-11-10 B ABBV 5.0 2020-11-12 S 26.0
您不必制作所有中间数据帧等,但我将代码留在这里,以便如果您将内容粘贴到笔记本中,您可以查看步骤。
【讨论】:
以上是关于熊猫在不同长度的列上合并两个数据框的主要内容,如果未能解决你的问题,请参考以下文章