如何在Pandas中合并含重复行的多个DataFrame?
解决方案
首先明确数据结构和填充规则:假设q为当月首日(示例值'2015-01-01'),对应入场价格为q_price;p为当月末日(示例值'2015-01-31'),对应出场价格为p_price,你可根据实际需求替换这些值。
步骤1:导入库并定义基础数据
import pandas as pd # 定义你提供的三个DataFrame df1 = pd.DataFrame({ 'Ticker': ['HAVELLS', 'TRITUR'], 'Entry Price': [1306.6, 115.43], 'Entry Date': ['2015-01-02', '2015-01-02'] }) df2 = pd.DataFrame({ 'Ticker': ['BRITANNIA', 'TRITUR'], 'Exit Price': [1200, 111.41], 'Exit Date': ['2015-01-09', '2015-01-09'] }) df3 = pd.DataFrame({ 'Ticker': ['TRITUR'], 'Entry Price': [112.01], 'Entry Date': ['2015-01-16'] }) # 定义当月首日、末日及对应价格(请根据实际情况修改) q = '2015-01-01' q_price = 100 # 示例值,替换为实际首日价格 p = '2015-01-31' p_price = 150 # 示例值,替换为实际末日价格
步骤2:整合入场和出场数据
把所有入场记录(df1+df3)和出场记录(df2)整理成统一格式,方便后续分组处理:
# 合并所有入场记录 entry_df = pd.concat([df1, df3]).reset_index(drop=True) entry_df['Type'] = 'Entry' # 转换出场记录格式,和入场对齐 exit_df = df2.rename(columns={'Exit Price': 'Price', 'Exit Date': 'Date'}) exit_df['Type'] = 'Exit' # 转换入场记录格式 entry_df = entry_df.rename(columns={'Entry Price': 'Price', 'Entry Date': 'Date'}) # 合并所有记录并按股票代码、日期排序 all_records = pd.concat([entry_df, exit_df]).sort_values(['Ticker', 'Date']).reset_index(drop=True)
步骤3:按Ticker分组处理出入场配对与缺失值填充
针对每个股票的记录,完成出入场配对,缺失部分用预设的当月首日/末日填充:
result_list = [] for ticker, group in all_records.groupby('Ticker'): # 分离入场和出场记录并按日期排序 entries = group[group['Type'] == 'Entry'].sort_values('Date').reset_index(drop=True) exits = group[group['Type'] == 'Exit'].sort_values('Date').reset_index(drop=True) max_len = max(len(entries), len(exits)) # 补充缺失的入场记录(用当月首日信息) if len(entries) < max_len: add_entries = pd.DataFrame({ 'Ticker': [ticker] * (max_len - len(entries)), 'Price': [q_price] * (max_len - len(entries)), 'Date': [q] * (max_len - len(entries)), 'Type': ['Entry'] * (max_len - len(entries)) }) entries = pd.concat([entries, add_entries]).sort_values('Date').reset_index(drop=True) # 补充缺失的出场记录(用当月末日信息) if len(exits) < max_len: add_exits = pd.DataFrame({ 'Ticker': [ticker] * (max_len - len(exits)), 'Price': [p_price] * (max_len - len(exits)), 'Date': [p] * (max_len - len(exits)), 'Type': ['Exit'] * (max_len - len(exits)) }) exits = pd.concat([exits, add_exits]).sort_values('Date').reset_index(drop=True) # 配对出入场记录 paired = pd.DataFrame({ 'Ticker': ticker, 'Entry Date': entries['Date'], 'Entry Price': entries['Price'], 'Exit Date': exits['Date'], 'Exit Price': exits['Price'] }) result_list.append(paired) # 合并所有结果 final_df = pd.concat(result_list).reset_index(drop=True)
最终结果示例
运行后final_df的格式如下:
| Ticker | Entry Date | Entry Price | Exit Date | Exit Price |
|---|---|---|---|---|
| BRITANNIA | 2015-01-01 | 100 | 2015-01-09 | 1200 |
| HAVELLS | 2015-01-02 | 1306.6 | 2015-01-31 | 150 |
| TRITUR | 2015-01-02 | 115.43 | 2015-01-09 | 111.41 |
| TRITUR | 2015-01-16 | 112.01 | 2015-01-31 | 150 |
逻辑说明
- 仅出场无入场的股票(如BRITANNIA):自动用当月首日
q填充入场信息; - 仅入场无出场的股票(如HAVELLS):自动用当月末日
p填充出场信息; - 多次出入场的股票(如TRITUR):按时间顺序配对,多余的入场记录用末日填充出场。
内容的提问来源于stack exchange,提问作者junfan02
相关产品推荐
相关产品推荐

