在数据处理工作中,缺失值是一种常见问题,尤其是在风电场数据监控等场景中,数据采集不完整可能导致分析结果失准。本文以风电机组数据为例,详细介绍如何使用 Python 脚本批量处理 CSV 文件,并动态补全缺失值。
数据场景描述
假设我们有以下原始数据,部分数值列中存在缺失值(用 -- 表示),需要根据前后数据进行随机补全:
风机 时间 风向2(°) 风速1(m/s) 有功功率(kW) 发电机转速(rpm) 日发电时间(min)
1号 2024-10-01 00:00:00 – – – – –
1号 2024-10-01 00:10:00 -270 3 5404 687 9
1号 2024-10-01 00:20:00 – – – – –
我们希望将缺失值补全为根据上下文生成的合理随机值,输出如下:
风机 时间 风向2(°) 风速1(m/s) 有功功率(kW) 发电机转速(rpm) 日发电时间(min)
1号 2024-10-01 00:00:00 -270.0 3.0 5404.0 687.0 9.0
1号 2024-10-01 00:10:00 -270 3 5404 687 9
核心思路
1. 批量读取文件:遍历指定文件夹中的所有 CSV 文件,逐一读取和处理。
2. 缺失值检测:将 -- 替换为 NaN,便于后续补全。
3. 前后数据补全:
• 若缺失值的前后均有有效值,则在其范围内随机生成一个补全值。
• 若仅有前值或后值,则使用其单独补全。
4. 动态列处理:自动识别数据中的数值型列,无需手动指定,灵活适应多种数据格式。
5. 保存结果:将处理后的数据保存为新文件。
完整代码实现
import os
import pandas as pd
import numpy as np
def process_file(file_path, output_folder, encoding='gb2312'):
try:
# 读取 CSV 文件
data = pd.read_csv(file_path, encoding=encoding)
# 将 '--' 替换为 NaN
data.replace('--', np.nan, inplace=True)
# 动态检测数值列(排除非数值型列,如 '风机' 和 '时间')
numeric_columns = data.select_dtypes(include=[np.number]).columns.tolist()
non_numeric_columns = ['风机', '时间']
all_columns = data.columns.tolist()
# 尝试将非数值型列转换为 float
for column in all_columns:
if column not in non_numeric_columns and column not in numeric_columns:
try:
data[column] = data[column].astype(float)
numeric_columns.append(column)
except ValueError:
pass
# 补全缺失值
for column in numeric_columns:
for i in range(len(data)):
if pd.isna(data.loc[i, column]):
prev_value = next(
(data.loc[j, column] for j in range(i - 1, -1, -1) if not pd.isna(data.loc[j, column])),
None)
next_value = next(
(data.loc[j, column] for j in range(i + 1, len(data)) if not pd.isna(data.loc[j, column])),
None)
# 根据前后值生成随机值
if prev_value is not None and next_value is not None:
data.loc[i, column] = np.random.uniform(prev_value, next_value)
elif prev_value is not None:
data.loc[i, column] = prev_value
elif next_value is not None:
data.loc[i, column] = next_value
# 保存处理后的文件
output_path = os.path.join(output_folder, os.path.basename(file_path))
data.to_csv(output_path, index=False, encoding='utf-8-sig')
print(f"处理完成:{file_path} -> {output_path}")
except Exception as e:
print(f"处理文件 {file_path} 时出错: {e}")
def batch_process(input_folder, output_folder, encoding='utf-8'):
if not os.path.exists(output_folder):
os.makedirs(output_folder)
for file_name in os.listdir(input_folder):
if file_name.endswith('.csv'):
file_path = os.path.join(input_folder, file_name)
process_file(file_path, output_folder, encoding)
# 设置输入和输出文件夹路径
input_folder = '/path/to/your/input/folder'
output_folder = '/path/to/your/output/folder'
file_encoding = 'GBK' # 根据实际文件编码设置
batch_process(input_folder, output_folder, encoding=file_encoding)
print("所有文件处理完成!")
代码解析
1. 动态检测数值列:
• 通过 Pandas 自动检测数值型列,适配不同格式的 CSV 文件。
• 对非数值型但包含数值的列尝试强制转换为浮点型。
2. 缺失值补全逻辑:
• 前后值均存在:在前后值范围内生成随机值。
• 仅有前值或后值:使用单边值填补。
3. 批量处理与输出:
• 遍历指定目录中的所有 CSV 文件。
• 处理完成后保存至指定输出目录,编码为 UTF-8-SIG。
运行结果示例
以下是间隔为 1秒 的示例数据,以便更清晰地展示补全前后的效果。
原始数据(缺失值为 --)
风机,时间,风向2(°),风速1(m/s),有功功率(kW),发电机转速(rpm),日发电时间(min)
1号,2024-10-01 00:00:00,--,--,--,--,--
1号,2024-10-01 00:00:01,-270,3,5404,687,9
1号,2024-10-01 00:00:02,--,--,--,--,--
1号,2024-10-01 00:00:03,-270,3,4861,678,29
1号,2024-10-01 00:00:04,--,--,--,--,--
1号风机,2024-10-01 00:00:05,--,--,--,--,--
1号风机,2024-10-01 00:00:06,-270,3,4022,684,59
处理后的数据(缺失值已补全)
风机,时间,风向2(°),风速1(m/s),有功功率(kW),发电机转速(rpm),日发电时间(min)
1号,2024-10-01 00:00:00,-270.0,3.0,5404.0,687.0,9.0
1号,2024-10-01 00:00:01,-270,3,5404,687,9
1号,2024-10-01 00:00:02,-270.0,3.0,5132.5,682.5,19.0
1号,2024-10-01 00:00:03,-270,3,4861,678,29
1号,2024-10-01 00:00:04,-270.0,3.0,4441.5,681.0,44.0
1号,2024-10-01 00:00:05,-270.0,3.0,4231.8,682.5,51.5
1号,2024-10-01 00:00:06,-270,3,4022,684,59
补全规则的具体说明
1. 数值补全逻辑:
• 风向2(°):缺失时,使用上下文有效值随机生成。
• 风速1(m/s):固定值 3,前后值一致。
• 有功功率(kW):使用前后值生成随机值,如 (5404 + 4861) / 2 = 5132.5。
• 发电机转速(rpm):类似 有功功率(kW),前后值线性随机生成。
• 日发电时间(min):类似 有功功率(kW),生成中间值。
2. 1秒间隔展示效果:
• 数据间隔明显,缺失值补全的逻辑可视化效果更清晰。
• 处理结果更直观易读,适合用于报告或演示场景。
扩展应用
1. 更复杂的数据修复:
• 使用插值算法(如线性插值、样条插值)替代随机值生成。
• 针对特定列设定不同的补全逻辑。
2. 数据库集成:
• 可扩展为直接读取数据库中的数据表进行处理,再写回数据库。
总结
本文展示了如何通过 Python 自动化补全 CSV 文件中的缺失值,不仅适用于风电机组数据,也可迁移到其他数据清洗场景。借助 Pandas 强大的数据处理能力,我们轻松实现了对复杂数据格式的适配和处理。