如何用Pandas基于子组件类型与数值实现配对并更新父组件计数?
问题描述
原始DataFrame结构如下:
| 子组件 | 数值 |
|---|---|
| A | 10 |
| B | 10 |
| C | 12 |
| D | 11 |
| A | 10 |
| A | 15 |
| D | 10 |
| E | 10 |
| F | 12 |
| G | 11 |
| H | 10 |
| F | 15 |
| F | 10 |
需要遵循以下规则实现子组件配对:
- 子组件A、B、C、D属于父组件Y组;E、F、G、H属于父组件Z组
- 仅当同一父组件组内所有子组件的数值差≤3时,才能组成对应父组件
- 每成功组成一个父组件,对应计数加1
期望输出结果:
| 子组件 | 数值 | 父组件 | 父组件计数 |
|---|---|---|---|
| A | 10 | Y | 1 |
| B | 10 | Y | 1 |
| C | 12 | Y | 1 |
| D | 11 | Y | 1 |
| A | 10 | N/A | N/A |
| A | 15 | N/A | N/A |
| D | 10 | N/A | N/A |
| E | 10 | Z | 1 |
| F | 12 | Z | 1 |
| G | 11 | Z | 1 |
| H | 10 | Z | 1 |
| F | 15 | N/A | N/A |
| F | 10 | N/A | N/A |
Pandas实现方案
步骤1:定义分组映射与初始化列
先定义子组件到父组件组的映射,给原始DataFrame添加目标列并初始化值为N/A。
import pandas as pd # 构造原始DataFrame data = { '子组件': ['A', 'B', 'C', 'D', 'A', 'A', 'D', 'E', 'F', 'G', 'H', 'F', 'F'], '数值': [10, 10, 12, 11, 10, 15, 10, 10, 12, 11, 10, 15, 10] } df = pd.DataFrame(data) # 子组件到父组件组的映射关系 group_map = { 'A': 'Y', 'B': 'Y', 'C': 'Y', 'D': 'Y', 'E': 'Z', 'F': 'Z', 'G': 'Z', 'H': 'Z' } # 初始化目标列 df['父组件'] = 'N/A' df['父组件计数'] = 'N/A'
步骤2:分组执行配对逻辑
按父组件组分别处理,每次尝试凑齐组内所有子组件各一个,检查数值差是否符合要求,符合则标记配对信息并移除已配对行,直到无法凑齐完整组为止。
# 遍历两个父组件组 for parent in ['Y', 'Z']: # 获取当前组包含的子组件列表 target_components = [k for k, v in group_map.items() if v == parent] pair_count = 0 while True: # 收集每个子组件未配对的第一行数据 candidate_rows = [] for comp in target_components: unpaired_rows = df[(df['子组件'] == comp) & (df['父组件'] == 'N/A')] if unpaired_rows.empty: break candidate_rows.append(unpaired_rows.iloc[0]) # 凑不齐完整子组件组则终止循环 if len(candidate_rows) != len(target_components): break # 检查数值差是否符合要求 values = [row['数值'] for row in candidate_rows] if max(values) - min(values) <= 3: pair_count += 1 # 更新配对成功行的父组件和计数 for row in candidate_rows: df.loc[row.name, '父组件'] = parent df.loc[row.name, '父组件计数'] = pair_count else: # 不符合条件的候选行标记为未配对,不再参与后续匹配 for row in candidate_rows: df.loc[row.name, '父组件'] = 'N/A'
步骤3:查看最终结果
执行代码后,打印DataFrame即可得到目标结果:
print(df.to_string(index=False))
内容的提问来源于stack exchange,提问作者fault_final
相关产品推荐
相关产品推荐

