当前位置:首页>python>拿到电价数据先别急着算:用 Python 做一遍数据清洗

拿到电价数据先别急着算:用 Python 做一遍数据清洗

  • 2026-06-28 13:52:44
拿到电价数据先别急着算:用 Python 做一遍数据清洗

很多人第一次做电力数据分析,会犯一个错误:

一拿到数据,就开始算平均值、画趋势图、做结论。

但真正有经验的数据分析人员,第一反应通常不是“赶紧分析”,而是先问:

这个数据能不能用?

比如你拿到一份现货电价表,里面有几千行数据。

你直接计算平均电价,结果发现某一天平均价特别高。

这时候你不能马上写结论:

该省现货电价显著上涨。

你要先检查:

这一列电价单位到底是元/MWh,还是元/kWh?

有没有缺失时段?

有没有重复记录?

有没有把日前价格和实时价格混在一起?

有没有把批发侧现货价格和用户侧零售电价混在一起?

有没有某一行录入错误,比如多写了一个 0?

有没有某些价格看起来极端,但其实是市场规则允许范围内的真实价格?

如果这些问题没处理,Python 算得越快,错误传播得也越快。

所以,本章我们先不追求模型。

不追求预测。

不追求策略。

先把最重要的基本功做好:

把一份原始电力数据,处理成一份能被分析的数据。

如果你是第一次接触电力数据清洗,这一章建议先收藏

本章不用你做复杂模型,只要理解三件事:

第一,电力数据不能拿来就算;

第二,缺失值、重复值、单位和口径必须先检查;

第三,Python 可以把这些检查动作变成可复用流程。

文末我准备了第4章配套资料包,包括完整代码、模拟原始数据、清洗后结果、按日统计结果、字段字典和清洗检查清单。

本文约9000字,阅读需要30分钟。满满干货,建议先起来,有空的时候慢慢看。

什么叫“数据处理”?

数据处理听起来很技术。

但简单来说,就是:

把乱的、不统一的、不完整的数据,整理成干净、统一、能计算、能追溯的数据。

比如你拿到一张电价表。

原始数据可能长这样:

省份
日期
时段
现货价格
山西
2026/01/01
00:00
320
山西
2026-01-01
01:00
缺失
山西
2026年1月1日
02:00
-50
山西
2026/01/01
03:00
99999

这张表显然不能直接分析。

因为:

日期格式不统一。

价格里有文字。

价格里有看起来很极端的数值。

同一列可能混入了不该出现的内容。

经过处理以后,我们希望它变成这样:

province
datetime
price_yuan_mwh
数据状态
山西
2026-01-01 00:00
320
正常样本
山西
2026-01-01 01:00
空值
缺失,待核验
山西
2026-01-01 02:00
-50
疑似异常,待核验
山西
2026-01-01 03:00
99999
疑似异常,待核验

也就是说,数据处理不是为了“把数据变好看”。

它是为了让后面的分析结果更可信。

这里要特别强调一点:

在电力市场数据处理中,看起来极端,不等于一定错误

有些数据确实可能是录入错误。

有些数据是缺失或格式问题。

但也有些数据,可能是市场运行中真实出现的极端价格。

比如在某些市场规则下,可能出现负价格、高价格或接近价格上下限的价格。

所以,更稳妥的做法不是一上来就删除,而是:

先标记,再核验,再决定如何处理。

电力数据从哪里来?

这一节非常重要。

因为很多新手容易把“网上看到的数据”“公众号截图里的数据”“别人转发的 Excel”都当成可靠数据。

但电力交易数据有很强的规则属性和口径属性。

同样叫“电价”,可能完全不是一回事。

所以我们先建立一个原则:

数据来源越接近官方发布、交易平台、原始披露,可信度通常越高;

经过多次转载、截图、二次加工的数据,需要谨慎核验。


1. 国家能源局:适合看宏观统计和市场总体情况

国家能源局会发布全国电力工业统计、全社会用电量、电力市场交易电量等数据。

例如,国家能源局发布的数据显示,2025 年全社会用电量累计为 103682 亿千瓦时,同比增长 5.0%。

这类数据适合用来理解全国用电规模、产业用电结构和宏观趋势。

国家能源局也发布全国电力市场交易电量数据。

2025 年 1—12 月,全国累计完成电力市场交易电量 66394 亿千瓦时,占全社会用电量比重 64.0%;其中,中长期交易电量 63522 亿千瓦时,现货交易电量 2872 亿千瓦时

这类数据适合做:

全国电力市场规模分析。

电力市场化交易趋势分析。

中长期、现货、绿电交易规模对比。

行业研究文章中的宏观背景引用。

但它不适合直接拿来做某个用户的电费测算。

因为宏观统计数据解决的是“全国总体情况”。

而用户电费测算需要的是:

具体省份、具体用户类别、具体电压等级、具体用电曲线、具体购电方式、具体价格口径、具体结算规则。

这两个场景不能混在一起。


2. 电力交易中心官网:适合查市场规则、公告、部分交易结果

如果你要研究某个省份的电力交易,优先应该看:

该省电力交易中心。

区域电力交易中心。

国家能源局派出机构网站。

省级发改委、能源局相关栏目。

因为电力交易规则具有很强的地方差异。

同样是现货市场,不同省份的运行阶段、出清机制、价格披露方式、数据下载格式,都可能不同。

《电力市场运行基本规则》明确,电力市场成员包括经营主体、电力市场运营机构和提供输配电服务的电网企业。

其中,电力市场运营机构包括电力交易机构和电力调度机构。

电力市场运营机构按职责负责电力市场交易、电力调度和交易结果执行,以及配套的准入注册、计量结算、信息披露等工作。

《电力市场运行基本规则》也明确,电力市场交易类型包括:

电能量交易、电力辅助服务交易、容量交易。

其中,电能量交易又按交易周期分为:

电力中长期交易、电力现货交易。

这说明,交易数据不是孤立存在的。

它一定和市场规则、交易类型、披露范围绑定在一起。

国家层面的基本规则还要求信息披露遵循“安全、及时、真实、准确、完整、易于使用”的原则,市场运营机构在确保信息安全基础上,按要求向经营主体和社会公众披露电力市场运行信息。

但这里要特别注意:

不是所有数据都对社会公众开放。

有些数据属于公众信息。

有些数据只对市场成员开放。

有些数据需要登录平台。

有些数据可能只能下载 PDF。

有些数据可能只能查看,不能批量下载。


3. 免费数据和靠谱数据不是一回事

很多免费数据能看,但不一定适合直接分析。

比如:

截图数据,不适合批量分析。

PDF 表格,可能需要人工整理。

网页表格,可能格式经常变。

公众号转载数据,必须回到原始来源核验。

商业平台展示数据,需要确认授权和口径。

对初学者来说,建议优先使用两类数据:

第一类:官方公开统计数据。

第二类:自己构造的教学用模拟数据。

前者适合做行业研究。

后者适合练习 Python。

本章实操就使用教学用模拟数据。

因为我们当前的重点不是判断某个省份真实价格,而是学会一套通用的数据处理方法。

Pandas 进阶:电力数据清洗

在 Python 里,处理表格数据最常用的工具仍然是 Pandas。

第3章我们已经用 Pandas 读取过电价数据。

本章开始,我们要做更接近真实工作的清洗。

常见清洗动作包括:

  1. 统一列名;
  2. 转换日期格式;
  3. 把电价列转换成数字;
  4. 处理缺失值;
  5. 标记疑似异常值;
  6. 删除重复记录;
  7. 按省份、日期、时段筛选;
  8. 检查记录数是否完整。

1. 统一列名

真实数据里,列名可能是中文:

省份、日期、时段、现货价格

也可能是英文:

province、date、time、price

也可能不同文件写法不一致:

价格、市场价格、日前价格、实时价格、节点电价、统一出清价格

为了方便代码复用,最好统一成固定列名。

比如:

provincedatetimeprice_yuan_mwh

这样后面的代码就不用反复改。

但真实业务中还应该多保留几个口径字段,例如:

market_typeprice_typedata_sourcepublish_date

比如:

market_type 可以记录是中长期、现货、绿电还是辅助服务。

price_type 可以记录是日前价格、实时价格、结算价格还是零售价格。

data_source 可以记录数据来源。

publish_date 可以记录发布时间。

这些字段看起来繁琐,但非常有用。

因为电力数据分析最怕的不是不会算,而是算错口径。


2. 处理缺失值

缺失值就是数据为空。

比如:

某个时段没有价格。

某一行日期为空。

某一行省份为空。

某一行价格写成了“缺失”。

缺失值不能直接忽略。

你要先判断它影响什么。

如果只是某一个时段价格缺失,可以先标记出来。

如果整行关键字段都缺失,可能需要删除。

如果做正式分析,还要回到原始来源核验。

小白阶段先记住一句话:

不要看到空值就随便填 0。

因为电价缺失不等于电价为 0。

负荷缺失也不等于用户没用电。

如果你把缺失价格填成 0,平均价格会被拉低。

后面的价差分析、收益测算、趋势判断都可能失真。


3. 处理疑似异常值

疑似异常值,就是看起来不太合理、需要进一步核验的数据。

比如:

价格字段出现文字。

电价多了一个 0。

单位搞错。

日期错位。

重复粘贴。

价格远远超出常见范围。

但电力市场里有一个特殊点:

有些看起来异常的价格,未必一定是错误。

比如在某些市场规则下,可能出现负价格、极端高价或接近限价的价格。

所以,正式业务中不能只凭感觉删除。

更稳妥的做法是:

先标记。

再核验。

再决定是否删除、修正、保留或单独说明。

本章代码会用一个教学规则:

价格小于 0 或大于 1500 元/MWh,先标记为“疑似异常/待核验”。

*注意:这只是为了演示 Pandas 如何筛选和标记数据。不代表任何省份真实现货市场价格上下限。真实业务中,负价格或高价格未必一定是错误值,必须结合当地市场规则、价格上下限、日前/实时口径、结算口径和原始披露文件进行核验。

Pandas 进阶:筛选与分组

清洗完数据后,我们通常要做筛选。

比如:

筛选某个省份。

筛选某一天。

筛选某个时间段。

筛选高价样本。

筛选疑似异常数据。

Pandas 很适合做这些事情。

比如:

df[df["province"] == "山西"]

这表示筛选省份为“山西”的数据。

再比如:

df[df["price_yuan_mwh"] > 500]

这表示筛选电价高于 500 元/MWh 的数据。

分组则适合做统计。

比如:

按日期统计样本平均电价。

按月份统计样本最高电价。

按省份统计价格波动。

本章实操会做一个最基础的分组:

按日期统计清洗后样本平均电价、样本最高电价、样本最低电价和样本价差。

这里要特别注意:

如果某一天原本应该有 24 个、48 个或 96 个价格点,但你的数据只有一部分,那么你算出来的平均值只能叫“样本平均值”。

不能直接叫“完整日均价”。

所以本章代码里会保留一个字段:

record_count

它用来提示当天实际参与统计的数据条数。

同时,代码里还会加入两个教学字段:

expected_record_countis_record_count_complete

expected_record_count 表示教学假设下当天应有的记录数。

is_record_count_complete 表示样本记录数是否完整。

这两个字段可以帮助你更直观地理解:

只有记录数完整,统计结果才更有解释基础;

记录数不完整时,只能谨慎称为样本统计结果。

电力数据的时间处理:为什么日期格式特别重要?

电力交易数据和普通表格最大的区别之一,是它非常依赖时间。

比如:

现货价格按小时或更短时段变化。

负荷数据可能是 15 分钟一个点。

分时电价有尖峰、峰、平、谷。

中长期交易有年、月、周、多日等周期。

如果时间处理错了,后面分析一定错。

比如:

你把:

2026/01/02 00:00

识别成文本,而不是时间。

那 Python 就没法按日期排序、按月份统计、按小时筛选。

所以本章会把日期和时段合并成一个标准时间字段:

datetime

比如:

2026-01-01 08:00

有了这个字段,后面才能继续做:

按日统计。

按月统计。

按小时筛选。

画时间序列图。

计算峰谷价差。

检查缺失时段。

示例数据说明

本章实操使用一份教学用模拟“省级现货电价数据”。

文件名:

spot_price_raw.csv

字段如下:

字段名
含义
province
省份
date
日期
time
时段
price_yuan_mwh
价格,单位:元/MWh

注意:

本章使用的是教学用模拟数据

它不是任何省份真实现货电价。

不代表真实出清价格、结算价格或交易规则。

这里使用“元/MWh”,是因为现货市场价格数据常见单位之一是元/兆瓦时。

如果要换算成元/kWh,可以用:

元/kWh = 元/MWh ÷ 1000

比如:

500 元/MWh = 0.5 元/kWh

单位千万不能搞错。

元/MWh 和元/kWh 相差 1000 倍。

如果单位错了,后面所有电费计算、收益测算和价格比较都会错。

为了减少路径报错,建议把本章代码放在一个简单英文路径中,例如:

D:\python_power_trade\chapter04

本章代码会自动在这个文件夹中创建和读取:

spot_price_raw.csv

处理完成后,也会把结果文件导出到同一个文件夹中。

Python 完整代码

本章代码会自动创建一份带有“缺失值、疑似异常值、重复值”的模拟数据,然后完成读取、清洗、筛选、分组和导出。

先安装依赖:

python -m pip install pandas

如果 Windows 上 python 命令不生效,可以尝试:

py -m pip install pandas

如果下载较慢,可以使用国内镜像源:

python -m pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple

或者:

py -m pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple

新建文件:

chapter04_clean_spot_price.py

下面这段代码不要求你一次性全部看懂。

第4章的目标只有一个:

把一份带有缺失值、重复值、异常值和单位问题的模拟电价数据,清洗成可以继续分析的数据。

如果你不想手动整理文件,可以在文末私信关键词领取本章资料包,里面已经准备好代码、原始数据、清洗结果和运行说明。

复制下面代码运行:

# -*- coding: utf-8 -*-# 第4章实操:电力交易数据处理——从原始现货电价数据到可分析数据# 说明:# 1. 本案例使用教学用模拟数据,不代表任何省份真实现货电价或交易规则# 2. 本案例仅用于 Python 数据处理教学,不构成交易建议、投资建议或收益承诺from pathlib import Pathimport pandas as pdprint("=== Python电力交易第4章:电力交易数据清洗与筛选 ===")# 1. 找到当前 Python 文件所在的文件夹current_folder = Path(__file__).resolve().parent# 2. 设置输入和输出文件路径raw_file = current_folder / "spot_price_raw.csv"clean_output_file = current_folder / "spot_price_cleaned.csv"summary_output_file = current_folder / "spot_price_daily_summary.csv"# 3. 如果文件不存在,自动创建一份教学用模拟数据ifnot raw_file.exists():    sample_data = [        ["山西""2026/01/01""00:00""320"],        ["山西""2026/01/01""01:00""310"],        ["山西""2026/01/01""02:00"""],          # 缺失价格        ["山西""2026/01/01""03:00""305"],        ["山西""2026/01/01""04:00""-50"],       # 教学用疑似异常值        ["山西""2026/01/01""05:00""299"],        ["山西""2026/01/01""06:00""420"],        ["山西""2026/01/01""07:00""580"],        ["山西""2026/01/01""08:00""760"],        ["山西""2026/01/01""09:00""99999"],     # 教学用疑似异常值        ["山西""2026/01/01""10:00""650"],        ["山西""2026/01/01""10:00""650"],       # 重复记录        ["山西""2026/01/02""00:00""280"],        ["山西""2026/01/02""01:00""275"],        ["山西""2026/01/02""02:00""缺失"],      # 非数字        ["山西""2026/01/02""03:00""260"],        ["山西""2026/01/02""04:00""300"],        ["山西""2026/01/02""05:00""360"],        ["山东""2026/01/01""00:00""350"],        ["山东""2026/01/01""01:00""340"],        ["山东""2026/01/01""02:00""330"],        ["山东""2026/01/01""03:00""390"],    ]    sample_df = pd.DataFrame(        sample_data,        columns=["province""date""time""price_yuan_mwh"]    )    sample_df.to_csv(raw_file, index=False, encoding="utf-8-sig")    print(f"\n未发现 {raw_file.name},已自动创建教学用模拟数据。")else:    print(f"\n已发现 {raw_file.name},将直接读取该文件。")# 4. 读取原始数据df = pd.read_csv(raw_file, encoding="utf-8-sig")# 5. 检查必要字段是否存在required_columns = ["province""date""time""price_yuan_mwh"]for column in required_columns:if column notin df.columns:raise ValueError(f"CSV 文件中缺少必要字段:{column}")print("\n【1】原始数据预览:")print(df.head(10))print("\n原始数据行数:", len(df))# 6. 去除完全重复的记录df = df.drop_duplicates()print("\n【2】删除重复记录后的数据行数:", len(df))# 7. 把价格列转换为数字# errors='coerce' 的意思是:如果遇到无法转换成数字的内容,就变成空值 NaNdf["price_yuan_mwh"] = pd.to_numeric(df["price_yuan_mwh"], errors="coerce")print("\n【3】价格列转换为数字后的数据:")print(df.head(10))# 8. 合并 date 和 time,生成 datetime 字段df["datetime"] = pd.to_datetime(    df["date"].astype(str) + " " + df["time"].astype(str),    errors="coerce")# 9. 从 datetime 中提取日期、小时、月份df["trade_date"] = df["datetime"].dt.datedf["hour"] = df["datetime"].dt.hourdf["month"] = df["datetime"].dt.to_period("M")# 10. 标记缺失价格df["is_missing_price"] = df["price_yuan_mwh"].isna()# 11. 标记疑似异常价格# 注意:这里只是教学用筛选规则,不代表任何省份真实价格上下限# 在真实业务中,负价格或高价格未必一定是错误值,应回到原始披露和市场规则中核验df["is_suspicious_price"] = (    (df["price_yuan_mwh"] < 0) |    (df["price_yuan_mwh"] > 1500))print("\n【4】缺失价格记录:")print(df[df["is_missing_price"] == True])print("\n【5】疑似异常价格记录:")print(df[df["is_suspicious_price"] == True])# 12. 生成清洗后的数据# 本案例中,为了演示后续统计流程,临时剔除价格缺失、疑似异常价格和时间无法识别的数据# 真实业务中不建议直接删除问题数据,应先标记、再核验、保留处理记录clean_df = df[    (df["is_missing_price"] == False) &    (df["is_suspicious_price"] == False) &    (df["datetime"].notna())].copy()print("\n【6】清洗后的样本数据预览:")print(clean_df.head(10))print("\n清洗后样本数据行数:", len(clean_df))# 13. 筛选某个省份的数据target_province = "山西"province_df = clean_df[clean_df["province"] == target_province].copy()print(f"\n【7】筛选 {target_province} 数据:")print(province_df.head(10))# 14. 筛选教学阈值下的高价样本# 这里设置教学用阈值:价格高于 600 元/MWh,标记为高价样本# 真实业务中不能把 600 元/MWh 直接作为通用高价判断标准high_price_df = province_df[province_df["price_yuan_mwh"] > 600].copy()print("\n【8】教学阈值下的高价样本:")print(high_price_df[["province""datetime""price_yuan_mwh"]])# 15. 按日期分组统计# 注意:这里统计的是清洗后样本数据,不代表完整自然日全部时段的真实日均价格daily_summary = province_df.groupby("trade_date").agg(    sample_avg_price=("price_yuan_mwh""mean"),    sample_max_price=("price_yuan_mwh""max"),    sample_min_price=("price_yuan_mwh""min"),    record_count=("price_yuan_mwh""count")).reset_index()# 16. 新增样本价差字段daily_summary["sample_price_spread"] = (    daily_summary["sample_max_price"] - daily_summary["sample_min_price"])# 17. 新增记录数完整性检查字段# 这里假设教学场景下,一天应有 24 个小时级价格点# 真实业务中应根据当地市场数据颗粒度改成 24、48、96 或其他值expected_record_count = 24daily_summary["expected_record_count"] = expected_record_countdaily_summary["is_record_count_complete"] = (    daily_summary["record_count"] == daily_summary["expected_record_count"])print("\n【9】按日样本统计结果:")print(daily_summary)print("\n提示:record_count 表示当天参与统计的样本记录数。")print("expected_record_count 表示教学假设下当天应有的记录数。")print("is_record_count_complete 用于提示样本记录数是否完整。")print("真实业务中,应根据当地市场数据颗粒度设置应有记录数,例如 24、48 或 96。")# 18. 新增价格单位换算字段clean_df["price_yuan_kwh"] = clean_df["price_yuan_mwh"] / 1000print("\n【10】价格单位换算示例:")print(clean_df[["province""datetime""price_yuan_mwh""price_yuan_kwh"]].head())# 19. 导出清洗结果和按日统计结果clean_df.to_csv(clean_output_file, index=False, encoding="utf-8-sig")daily_summary.to_csv(summary_output_file, index=False, encoding="utf-8-sig")print("\n处理完成!已生成两个文件:")print(clean_output_file.name)print(summary_output_file.name)print("\n再次提醒:本章疑似异常规则和高价阈值仅用于教学。")print("真实业务中必须根据当地最新交易规则、价格上下限、数据口径和原始披露文件重新核验。")

代码解释

1. 文件编码声明

# -*- coding: utf-8 -*-

这一行表示代码文件使用 UTF-8 编码。

现在大多数新版编辑器默认支持 UTF-8,所以这行通常不是必须的。

但对零基础读者来说,保留这一行可以减少少数电脑上中文乱码的概率。


2. 导入工具库

from pathlib import Pathimport pandas as pd

这里导入了两个工具。

pathlib 是 Python 自带的路径处理工具,用来帮助程序找到文件位置。

pandas 用来读取和处理表格数据。

其中:

import pandas as pd

意思是把 pandas 简写成 pd

这是数据分析中非常常见的写法。


3. 找到当前代码文件所在文件夹

current_folder = Path(__file__).resolve().parent

这行代码的意思是:

找到当前这个 Python 文件所在的文件夹。

为什么要这样写?

因为很多新手会遇到一个问题:

明明 CSV 文件和 Python 文件放在同一个文件夹里,但运行时还是提示找不到文件。

原因通常是:

Python 当前运行位置,和代码文件实际所在位置不一致。

使用这一行代码后,程序会从“当前 Python 文件所在文件夹”去生成、读取和导出文件,路径更稳定。


4. 设置输入和输出文件路径

raw_file = current_folder / "spot_price_raw.csv"clean_output_file = current_folder / "spot_price_cleaned.csv"summary_output_file = current_folder / "spot_price_daily_summary.csv"

这三行代码表示:

spot_price_raw.csv 是原始模拟数据文件。

spot_price_cleaned.csv 是清洗后的样本明细数据。

spot_price_daily_summary.csv 是按日样本统计结果。

它们都会放在当前 Python 文件所在文件夹中。

也就是说,代码运行后,你可以在同一个文件夹里看到:

chapter04_clean_spot_price.pyspot_price_raw.csvspot_price_cleaned.csvspot_price_daily_summary.csv

这样对新手更友好,不容易找不到文件。


5. 自动创建模拟数据

ifnot raw_file.exists():

这行代码的意思是:

如果当前文件夹里没有 spot_price_raw.csv,就自动创建一份模拟数据。

这样做是为了降低新手运行门槛。

你不需要先手动准备文件,只要复制代码,就能跑通。

*但要注意:自动创建的数据是教学用模拟数据,不是山西、山东或任何省份的真实现货价格。


6. 读取 CSV 文件

df = pd.read_csv(raw_file, encoding="utf-8-sig")

这行代码用 Pandas 读取 CSV 文件。

encoding="utf-8-sig" 是为了减少中文乱码问题。

读入之后,df 就是一张 Python 表格。


7. 检查必要字段是否存在

required_columns = ["province""date""time""price_yuan_mwh"]for column in required_columns:if column notin df.columns:raise ValueError(f"CSV 文件中缺少必要字段:{column}")

这段代码的意思是:

检查 CSV 文件里是否有以下 4 个必要字段:

provincedatetimeprice_yuan_mwh

如果缺少某一列,程序会主动报错,并提示缺少哪个字段。

这样比直接出现 KeyError 更适合新手理解。

比如你把表头写成:

price

程序就会提示缺少:

price_yuan_mwh

小白阶段建议先不要改字段名,先完整跑通示例代码。


8. 删除重复记录

df = df.drop_duplicates()

这行代码会删除完全相同的重复行。

在电力数据中,重复记录很常见。

可能是人工复制导致的。

也可能是多次导出合并导致的。

如果不删除重复记录,平均价格、记录数量、分组统计都可能被影响。


9. 把价格列转换为数字

df["price_yuan_mwh"] = pd.to_numeric(df["price_yuan_mwh"], errors="coerce")

这行代码很重要。

原始数据里,价格列可能混入:

空白缺失-文字

这些内容不能直接参与计算。

errors="coerce" 的意思是:

如果某个值无法转换成数字,就把它变成空值。

这样后面就能统一处理缺失价格。


10. 合并日期和时段

df["datetime"] = pd.to_datetime(    df["date"].astype(str) + " " + df["time"].astype(str),    errors="coerce")

这段代码把 date 和 time 合并成一个完整时间。

比如:

2026/01/01 + 08:00

变成:

2026-01-01 08:00:00

有了 datetime 字段,后面才方便按小时、按日、按月统计。


11. 提取日期、小时、月份

df["trade_date"] = df["datetime"].dt.datedf["hour"] = df["datetime"].dt.hourdf["month"] = df["datetime"].dt.to_period("M")

这三行分别提取:

交易日期。

小时。

月份。

这在电力交易数据处理中非常常用。

例如:

按日统计样本平均电价。

按小时看高价样本分布。

按月比较价格波动。


12. 标记缺失价格

df["is_missing_price"] = df["price_yuan_mwh"].isna()

这行代码会新增一列:

is_missing_price

如果价格为空,就是 True

如果价格不为空,就是 False

这样做的好处是:

你不会悄悄把问题数据删掉。

而是先明确看到哪些数据有问题。


13. 标记疑似异常价格

df["is_suspicious_price"] = (    (df["price_yuan_mwh"] < 0) |    (df["price_yuan_mwh"] > 1500))

这段代码会标记教学口径下的疑似异常价格。

这里用了两个条件:

价格小于 0。

价格大于 1500。

只要满足其中一个条件,就标记为疑似异常。

再次强调:

这只是教学规则

真实业务中,负价格或高价格不一定是错误数据。

是否需要删除、修正或保留,必须结合:

省份规则、价格上下限、交易品种、日前或实时、出清价格或结算价格、数据单位、市场运行阶段、原始披露文件等。

不能照搬本章规则。


14. 清洗数据

clean_df = df[    (df["is_missing_price"] == False) &    (df["is_suspicious_price"] == False) &    (df["datetime"].notna())].copy()

这段代码保留三类数据:

价格不缺失。

没有被教学规则标记为疑似异常。

时间可以识别。

最终得到一份相对干净的数据:

clean_df

但要注意:

本章是为了教学演示,临时剔除了这些问题数据。

真实业务中不建议直接删除问题数据。

而是:先标记、再核验、保留处理记录。

最后再决定是否剔除、修正或单独说明。


15. 筛选某个省份

target_province = "山西"province_df = clean_df[clean_df["province"] == target_province].copy()

这段代码筛选出山西的数据。

如果你想看山东,只需要改成:

target_province = "山东"

这就是代码模板的价值。

不用重写整套代码,只改一个参数即可。


16. 筛选教学阈值下的高价样本

high_price_df = province_df[province_df["price_yuan_mwh"] > 600].copy()

这行代码筛选价格高于 600 元/MWh 的样本。

但这里的 600 只是教学阈值。

真实业务中不能简单认为:

高于 600 就一定高。

低于 600 就一定低。

你要看:

省份、日期、市场类型、价格单位、历史分布、交易规则、用户或项目的业务场景。

更不能写成:

高于 600 元/MWh 就适合储能套利。

这是典型的误导性表达。


17. 按日期分组统计

daily_summary = province_df.groupby("trade_date").agg(    sample_avg_price=("price_yuan_mwh""mean"),    sample_max_price=("price_yuan_mwh""max"),    sample_min_price=("price_yuan_mwh""min"),    record_count=("price_yuan_mwh""count")).reset_index()

这段代码按日期分组,并计算:

清洗后样本平均电价。

清洗后样本最高电价。

清洗后样本最低电价。

参与统计的样本记录数。

这里特别使用了 sample_ 前缀。

这是为了提醒你:

它统计的是清洗后的样本数据。

不是完整自然日全部时段的真实市场统计结果。

如果某一天缺少多个时段,或者部分时段被标记后剔除,那么当天的平均价、最高价、最低价,都只能作为样本统计结果。


18. 计算样本价差

daily_summary["sample_price_spread"] = (    daily_summary["sample_max_price"] - daily_summary["sample_min_price"])

这行代码计算:

样本价差 = 样本最高价 - 样本最低价

价差是电力市场分析里很常见的指标。

但注意:

看到价差大,不等于一定能套利。

是否能套利,还要考虑:

储能效率、充放电约束、容量、电量、循环次数、交易规则、辅助服务、损耗、成本、税费、结算方式、偏差考核、市场准入条件等。

所以,本章只讲数据处理,不做收益判断。


19. 记录数完整性检查

代码中有一个字段:

record_count

它表示当天参与统计的样本记录数。

这个字段不是装饰字段。

它非常重要。

本章代码里还新增了两个字段:

expected_record_countis_record_count_complete

其中:

expected_record_count 表示教学假设下当天应有的记录数。

is_record_count_complete 表示当天样本记录数是否完整。

代码如下:

expected_record_count = 24daily_summary["expected_record_count"] = expected_record_countdaily_summary["is_record_count_complete"] = (    daily_summary["record_count"] == daily_summary["expected_record_count"])

这里假设教学场景下,一天应有 24 个小时级价格点。

真实业务中,应根据当地市场数据颗粒度调整。

比如:

某市场一天是 24 个小时点。

某市场一天是 48 个半小时点。

某市场一天是 96 个 15 分钟点。

如果某个市场一天理论上应该有 24 个价格点。

但你清洗后只剩下 18 个价格点。

那这一天的平均价就不能直接当成完整日均价。

再比如某个市场一天理论上应该有 96 个价格点。

但你只拿到了 30 个点。

这时你更不能直接写结论。

正式业务中,你至少要检查:

应有记录数是多少。

实际记录数是多少。

缺失了哪些时段。

缺失原因是什么。

是否影响统计结果。

是否需要补充说明。


20. 价格单位换算

代码中新增了一列:

clean_df["price_yuan_kwh"] = clean_df["price_yuan_mwh"] / 1000

这行代码的意思是:

把元/MWh 换算成元/kWh。

换算关系是:

1 MWh = 1000 kWh

所以:

500 元/MWh = 0.5 元/kWh

这一步非常重要。

因为很多用户侧电价、电费计算,更习惯使用元/kWh。

而很多现货市场价格数据,常见单位是元/MWh。

如果单位不统一,后面的分析会全部错位。

运行结果说明

运行代码后,你会看到几类输出。

第一类是原始数据预览。

你会看到数据里故意设计了:

缺失价格。

非数字价格。

疑似异常价格。

重复记录。

第二类是缺失价格记录。

比如:

price_yuan_mwh 为空price_yuan_mwh 无法转换成数字

第三类是疑似异常价格记录。

比如:

-5099999

*注意:它们只是被本章教学规则标记为疑似异常,不代表真实业务中一定应该删除。

第四类是清洗后的样本数据。

这些数据已经临时剔除了重复记录、缺失价格、疑似异常价格和无法识别时间的记录。

第五类是高价样本。

你会看到价格高于 600 元/MWh 的样本记录。

*600 元/MWh 只是教学阈值,不是真实市场高价判断标准

第六类是按日样本统计结果。

你会看到类似字段:

trade_datesample_avg_pricesample_max_pricesample_min_pricerecord_countsample_price_spreadexpected_record_countis_record_count_complete

其中:

record_count 表示当天实际参与统计的样本记录数。

expected_record_count 表示教学假设下当天应有记录数。

is_record_count_complete 表示样本记录数是否完整。

*本章输出的 daily_summary 是基于清洗后样本数据得到的统计结果。如果某一天原始数据缺少多个时段,或者部分时段被标记为疑似异常并剔除,那么当天的平均价、最高价、最低价和价差只能作为教学样本结果,不能直接代表完整自然日的真实市场价格水平。在正式业务中,应先检查当天应有记录数和实际记录数是否一致。例如某市场一天应有 24 个、48 个或 96 个价格点,就要检查数据是否完整。

最后,代码会生成两个文件:

spot_price_cleaned.csvspot_price_daily_summary.csv

第一个是清洗后的样本明细数据。

第二个是按日样本统计结果。

这两个文件会生成在当前 Python 文件所在文件夹中。

这就完成了一个基础数据处理闭环:

原始数据进来,清洗结果出去,统计结果出去。

本章小练习

练习 1:修改目标省

把代码中的:

target_province = "山西"

改成:

target_province = "山东"

重新运行代码。

观察筛选结果和按日样本统计结果是否变化。


练习 2:修改高价阈值

把代码中的:

price_yuan_mwh > 600

改成:

price_yuan_mwh > 500

重新运行代码。

观察高价样本数量是否变多。


练习 3:新增一条疑似异常数据

在 spot_price_raw.csv 里新增一行:

山西,2026/01/02,06:00,88888

重新运行代码。

看看它是否会被标记为疑似异常值。


练习 4:理解价格单位换算

观察代码中这一行:

clean_df["price_yuan_kwh"] = clean_df["price_yuan_mwh"] / 1000

然后打印:

print(clean_df[["province""datetime""price_yuan_mwh""price_yuan_kwh"]].head())

理解“元/MWh”和“元/kWh”的关系。


练习 5:观察记录数

查看 daily_summary 里的:

record_countexpected_record_countis_record_count_complete

思考一个问题:

如果某一天理论上应该有 24 个价格点,但你的 record_count 只有 8,这一天的样本平均电价还能不能直接代表完整日均价?

答案是:不能。

你只能说:这是基于现有样本计算得到的样本平均值。

本章小结

本章我们没有急着做模型,也没有直接画图分析价格趋势。

而是先完成了一件更基础、更重要的事:

把原始电力交易数据处理成相对可用的数据

你至少需要记住以下几点:

第一,电力数据分析的第一步不是画图,而是检查数据能不能用。

第二,数据来源、发布时间、适用省份、交易品种、价格单位都必须记录清楚。

第三,缺失价格不等于 0。

第四,元/MWh 和元/kWh 相差 1000 倍,不能混用。

第五,现货日前价格、实时价格、中长期价格、零售价格、分时电价不能混在一起分析。

第六,负价格或极端价格不一定是错误数据,应先标记、再核验。

第七,清洗后样本平均值不等于完整自然日真实日均价。

第八,record_count 可以帮助你判断数据是否完整。

第九,Python 是工具,数据口径和业务规则才是分析可信度的基础。

这章看起来是在讲 Pandas。

但真正想让你建立的是一种工作习惯:

先查口径,再清洗数据;

先保留问题,再做判断;

先验证完整性,再输出结论。

这才是电力交易数据分析最重要的基本功

资料领取

如果你已经跑通本章代码,欢迎在评论区回复:

清洗模板已跑通

如果你遇到问题,也可以直接留言报错信息,比如:

ValueError

FileNotFoundError

ModuleNotFoundError

日期转换失败

中文乱码

后续我会整理一篇:

《电力交易数据清洗最常见的10个坑》

如果你想直接领取本章配套资料,可以私信公众号关键词:

电力Python04

领取《Python电力交易》第4章数据清洗资料包,包括:

1.chapter04_clean_spot_price.py

2.spot_price_raw.csv 模拟原始数据

3.spot_price_cleaned.csv 清洗后样本数据

4.spot_price_daily_summary.csv 按日样本统计结果

5.第4章运行说明

6.电力交易常见数据字段字典

7.电价数据清洗检查清单

建议使用顺序:

先看运行说明 → 跑通完整代码 → 查看清洗前后数据变化 → 对照字段字典理解每一列含义 → 用清洗检查清单复盘自己的数据。

也欢迎你在评论区回答一个问题:

你平时拿到的电力数据,最常见的问题是什么?

A. 缺失值太多

B. 日期格式混乱

C. 表头不统一

D. 单位不清楚

E. PDF 复制困难

F. 不知道数据口径

G. 不知道哪些数据能删、哪些数据不能删

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-03 06:46:04 HTTP/2.0 GET : https://f.mffb.com.cn/a/498411.html
  2. 运行时间 : 0.105555s [ 吞吐率:9.47req/s ] 内存消耗:4,676.28kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=3774975fef110da8b06a09fc186d0719
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000681s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000755s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000328s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000258s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000485s ]
  6. SELECT * FROM `set` [ RunTime:0.000206s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000520s ]
  8. SELECT * FROM `article` WHERE `id` = 498411 LIMIT 1 [ RunTime:0.000522s ]
  9. UPDATE `article` SET `lasttime` = 1783032365 WHERE `id` = 498411 [ RunTime:0.013841s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000353s ]
  11. SELECT * FROM `article` WHERE `id` < 498411 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000549s ]
  12. SELECT * FROM `article` WHERE `id` > 498411 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000409s ]
  13. SELECT * FROM `article` WHERE `id` < 498411 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.002641s ]
  14. SELECT * FROM `article` WHERE `id` < 498411 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.007255s ]
  15. SELECT * FROM `article` WHERE `id` < 498411 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.008957s ]
0.107155s