使用Pandas合并DataFrame中成对交易行并保留原两行数据
解决方案
你可以通过以下步骤用Pandas实现交易记录的配对合并:
- 为每组交易添加组内索引:通过
groupby.cumcount()给同一交易对(按Traders (alphabetical)分组)的两行分别标记0和1,用于后续配对。 - 创建镜像数据集并重命名列:复制原数据集,反转组内索引(
0变1,1变0),并将所有列名加上_y后缀,作为配对的对手方数据。 - 按交易组和组内索引合并数据集:将原数据集与镜像数据集合并,得到每行对应的对手方记录。
完整代码示例
import pandas as pd # 构造示例数据集(对应你的原始表格) data = [ ["John", "Mark", 100, 60, "John, Mark"], ["Mark", "John", 65, 90, "John, Mark"], ["Philip", "Isaac", 110, 20, "Isaac, Philip"], ["Isaac", "Philip", 20, 100, "Isaac, Philip"] ] df = pd.DataFrame( data, columns=["Counterparty A", "Counterparty B", "Amount payed", "Amount received", "Traders (alphabetical)"] ) # 步骤1:添加组内索引 df['idx'] = df.groupby('Traders (alphabetical)').cumcount() # 步骤2:创建镜像数据集并处理 df_y = df.copy() # 反转组内索引,确保配对正确 df_y['idx'] = df_y['idx'].map({0: 1, 1: 0}) # 重命名列,添加_y后缀 df_y.columns = [col + '_y' for col in df.columns] # 步骤3:合并数据集 result = pd.merge( df, df_y, left_on=['Traders (alphabetical)', 'idx'], right_on=['Traders (alphabetical)_y', 'idx_y'] ) # 清理多余列,保留所需字段 result = result.drop(columns=['Traders (alphabetical)', 'idx', 'Traders (alphabetical)_y', 'idx_y']) # 输出结果 print(result)
输出结果说明
运行后得到的DataFrame结构完全符合你的期望:每行的_x列是原记录,_y列是对应的交易对手方上报的记录,方便你直接对比金额差异。
如果需要在可视化时实现加粗/斜体的格式,可以使用Pandas的Styler功能:
def highlight_rows(val): # 为第一组的_x字段加粗,_y字段斜体;第二组同理反向 if val.name.startswith('Counterparty A_x') and 'John' in str(val): return 'font-weight: bold' elif val.name.startswith('Counterparty A_y') and 'Mark' in str(val): return 'font-style: italic' elif val.name.startswith('Counterparty A_x') and 'Mark' in str(val): return 'font-style: italic' elif val.name.startswith('Counterparty A_y') and 'John' in str(val): return 'font-weight: bold' return '' styled_result = result.style.applymap(highlight_rows) styled_result.to_html('交易对比表.html', index=False)
内容的提问来源于stack exchange,提问作者cocobolo
相关产品推荐
相关产品推荐

