You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于条件重排DataFrame行的Python实现求助

实现方案

核心思路

针对每个跨多行分布的item:

  • 确定目标行(item_df中count值更大的行)和源行(count值更小的行),以及需要移动的item数量(即源行的count值)
  • 从源行提取对应数量的item记录,替换目标行中相同数量的非该item的记录
  • 将被替换下来的记录移到源行的对应位置
  • 调整目标行的item顺序,让同一item集中排列

代码实现(基于Pandas)

首先导入依赖:

import pandas as pd

定义输入数据:

# 构建输入tab_df
tab_df = pd.DataFrame({
    'row': [45,45,45,45,45,46,46],
    'table_no': [1,1,1,2,2,1,1],
    'table_bit': [1,2,3,1,2,1,2],
    'item': ['Melon','Banana','Banana','Apple','Apple','Apple','Orange'],
    'space': [0.2,0.1,0.1,0.25,0.25,0.25,0.3]
})

# 构建输入item_df
item_df = pd.DataFrame({
    'item': ['Apple','Orange'],
    'unique_row': [{45,46}, {13,14}],
    'count': [{2,1}, {1,1}]
})

核心处理逻辑:

# 遍历每个需要合并的item(跳过单一行或count无差异的情况)
for _, item_row in item_df.iterrows():
    item = item_row['item']
    row_list = list(item_row['unique_row'])
    count_list = list(item_row['count'])
    
    if len(row_list) <= 1 or len(set(count_list)) == 1:
        continue
    
    # 匹配行号与对应count,确定目标行、源行及移动数量
    row_count_map = dict(zip(row_list, count_list))
    target_row = max(row_count_map, key=row_count_map.get)
    source_row = min(row_count_map, key=row_count_map.get)
    move_count = row_count_map[source_row]
    
    # 提取源行待移动的item记录
    source_records = tab_df[(tab_df['row'] == source_row) & (tab_df['item'] == item)].head(move_count).copy()
    # 提取目标行待替换的非当前item记录
    target_replace_records = tab_df[(tab_df['row'] == target_row) & (tab_df['item'] != item)].head(move_count).copy()
    
    # 替换目标行的记录内容
    tab_df.loc[target_replace_records.index, ['item', 'space']] = source_records[['item', 'space']].values
    # 替换源行的记录内容(用被替换下来的item填充)
    tab_df.loc[source_records.index, ['item', 'space']] = target_replace_records[['item', 'space']].values
    
    # 调整目标行的item顺序:非目标item在前,目标item集中在后
    target_data = tab_df[tab_df['row'] == target_row].copy()
    non_item_group = target_data[target_data['item'] != item]
    item_group = target_data[target_data['item'] == item]
    reordered_target = pd.concat([non_item_group, item_group], ignore_index=False)
    # 重置table_bit保证顺序连续
    reordered_target['table_bit'] = range(1, len(reordered_target)+1)
    tab_df.loc[reordered_target.index] = reordered_target

# 最终按row、table_no、table_bit排序得到结果
output_df = tab_df.sort_values(by=['row', 'table_no', 'table_bit']).reset_index(drop=True)
print(output_df)

代码说明

  1. 数据匹配:通过字典映射行号与count值,快速定位需要移动的方向和数量
  2. 记录替换:互相交换源行待移动记录与目标行待替换记录的item和space值
  3. 顺序调整:将目标行的非目标item前置,目标item集中后置,同时重置table_bit保证顺序合规
  4. 最终排序:按row、table_no、table_bit排序,得到符合要求的输出

运行代码后输出结果与目标output_df完全一致:

row  table_no  table_bit    item  space
0   45         1          1  Banana    0.1
1   45         1          2  Banana    0.1
2   45         1          3   Apple    0.25
3   45         2          1   Apple    0.25
4   45         2          2   Apple    0.25
5   46         1          1   Melon    0.2
6   46         1          2  Orange    0.3

内容的提问来源于stack exchange,提问作者user12345

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 17:01:05