无法将Pandas DataFrame整理为指定格式:数值列未正常填充
Pandas实体数据横向格式化问题修复
问题描述
现有Pandas DataFrame采用纵向结构存储实体数据:字母数字串为实体ID,其下方的日期、十进制数值分别对应该实体的实际值与期望值。目标是将数据转为横向格式(一行对应一个实体的完整信息),但使用给定的process函数处理后,所有实体的数值列均未填充,输出不符合预期。
原始DataFrame
import pandas as pd data = [ ["F00000191U", "F00000191U"], ["2022-09-30", "2022-12-20"], [0.546437, 0.546437638135], ["F00000191U", "F00000191U"], ["2022-09-30", "2022-12-20"], ["F00000191U", "F00000191U"], ["2022-09-30", "2022-12-20"], [0.546437, 0.517306000000000], ["F00000QAXU", "F00000QAXU"], ["2022-02-28", "2022-07-31"], ["E0USA00HCY", "E0USA00HCY"], [0.864700, 0.911518], ["F000016X81", "F000016X81"], [0.446887, 0.446887122753], ["F000016X81", "F000016X81"], [0.446887, 0.446887000000000], ["E0USA0073X", "E0USA0073X"], ["2023-03-07", "2023-03-14"], [0.836902, 0.993576], ["F00000SZIP", "F00000SZIP"], ] df = pd.DataFrame(data, columns=["Actual", "Expected"])
原处理代码问题分析
原process函数存在三个核心问题:
- 类型判断局限:原始DataFrame中的数值可能以字符串形式存储,直接用
isinstance(row[0], float)判断会漏掉这类数值。 - 逻辑优先级错误:第一个
if条件未加括号,or的优先级低于and,导致实体ID的判断逻辑混乱。 - 数据收集不完整:未处理实体仅有ID、无日期/数值的情况,且最后一组数据可能输出空值。
修复后的代码
import re import pandas as pd def process(df): # 初始化临时存储变量 actual_entity = None actual_date = None actual_value = None expected_entity = None expected_date = None expected_value = None for _, row in df.iterrows(): actual_val = row["Actual"] expected_val = row["Expected"] # 判断是否为实体ID(以F/E开头的字符串) if isinstance(actual_val, str) and (actual_val.startswith('F') or actual_val.startswith('E')): # 如果已有未输出的实体数据,先输出 if actual_entity is not None: yield { 'Actual Entity ID': actual_entity, 'Actual start date': actual_date, 'Actual Value': actual_value, 'Expected Entity ID': expected_entity, 'Expected date': expected_date, 'Expected val': expected_value } # 重置临时变量,存储新实体ID actual_entity = actual_val expected_entity = expected_val actual_date = None actual_value = None expected_date = None expected_value = None # 判断是否为日期格式 elif isinstance(actual_val, str) and re.fullmatch(r'\d{4}-\d{2}-\d{2}', actual_val): actual_date = actual_val expected_date = expected_val # 判断是否为数值(尝试转换为float) else: try: actual_value = float(actual_val) expected_value = float(expected_val) except (ValueError, TypeError): # 非数值则跳过 pass # 输出最后一组实体数据(过滤空实体) if actual_entity is not None: yield { 'Actual Entity ID': actual_entity, 'Actual start date': actual_date, 'Actual Value': actual_value, 'Expected Entity ID': expected_entity, 'Expected date': expected_date, 'Expected val': expected_value } # 调用函数生成新DataFrame result_df = pd.DataFrame(process(df)) print(result_df)
关键修改点
- 修正实体ID判断的逻辑括号,确保
startswith的两个条件被正确组合。 - 改用尝试转换为float的方式判断数值,兼容字符串格式的数值。
- 调整临时变量重置时机,确保每组实体数据独立存储。
- 增加最后一组数据的非空判断,避免输出无效空行。
输出效果
修复后的数据将按横向格式展示,每个实体的ID、日期、数值(若存在)会正确填充到对应列中,示例片段:
| Actual Entity ID | Actual start date | Actual Value | Expected Entity ID | Expected date | Expected val |
|---|---|---|---|---|---|
| F00000191U | 2022-09-30 | 0.546437 | F00000191U | 2022-12-20 | 0.546437638135 |
| F00000191U | 2022-09-30 | NaN | F00000191U | 2022-12-20 | NaN |
| F00000191U | 2022-09-30 | 0.546437 | F00000191U | 2022-12-20 | 0.517306 |
内容的提问来源于stack exchange,提问作者Pratik
相关产品推荐
相关产品推荐

