问题分析
从错误日志中可以看到,代码在 report_services.py
的 gnss_monthly_report
函数中出现了 ValueError
,具体错误信息是:
ValueError: either both or neither of x and y should be given
这个错误发生在以下代码行:
report_data["V(ΔXY)"] = np.where(report_data['ΔXY'].diff().fillna(0) / 1, 0)
问题出在 np.where
的使用上。np.where
的语法是:
np.where(condition, x, y)
condition
:条件表达式。x
:当条件为True
时的返回值。y
:当条件为False
时的返回值。
在您的代码中,np.where
只提供了一个参数(report_data['ΔXY'].diff().fillna(0) / 1
),缺少了 x
和 y
参数,因此抛出了 ValueError
。
解决方案
修复 np.where
的使用,确保提供完整的参数。以下是修改后的代码:
# 修改前
report_data["V(ΔXY)"] = np.where(report_data['ΔXY'].diff().fillna(0) / 1, 0)# 修改后
report_data["V(ΔXY)"] = np.where(report_data['ΔXY'].diff().fillna(0) / 1 != 0, # 条件report_data['ΔXY'].diff().fillna(0) / 1, # 条件为 True 时的值0 # 条件为 False 时的值
)
shift
和 diff
函数的区别
1. shift
函数
-
功能:将数据沿着指定的轴移动指定的步长。
-
参数:
periods
:移动的步长,默认为1
。正数表示向下移动,负数表示向上移动。fill_value
:用于填充移动后产生的缺失值。
-
示例:
import pandas as pddata = pd.Series([1, 2, 3, 4, 5]) shifted_data = data.shift(1) print(shifted_data)
输出:
0 NaN 1 1.0 2 2.0 3 3.0 4 4.0 dtype: float64
-
应用场景:
- 计算滞后值(如上一行的值)。
- 计算滑动窗口统计量(如滑动平均值)。
2. diff
函数
-
功能:计算当前行与前一行的差值。
-
参数:
periods
:差分的步长,默认为1
。正数表示与前面的行计算差值,负数表示与后面的行计算差值。
-
示例:
import pandas as pddata = pd.Series([1, 2, 3, 4, 5]) diff_data = data.diff() print(diff_data)
输出:
0 NaN 1 1.0 2 1.0 3 1.0 4 1.0dtype: float64
-
应用场景:
- 计算时间序列数据的变化量。
- 计算数据的一阶差分(如速度、加速度)。
shift
和 diff
的区别
特性 | shift | diff |
---|---|---|
功能 | 移动数据,不改变数据本身的值 | 计算当前行与前一行的差值 |
返回值 | 移动后的数据,可能包含 NaN | 差值数据,第一行通常为 NaN |
参数 | periods (步长)、fill_value (填充值) | periods (步长) |
应用场景 | 滞后值计算、滑动窗口统计 | 变化量计算、一阶差分 |
修复后的完整代码示例
以下是修复后的完整代码片段:
# 计算 ΔXY 变化速率 (V(ΔXY))
delta_xy_diff = report_data['ΔXY'].diff().fillna(0) # 计算 ΔXY 的变化量
delta_xy_shift = report_data['ΔXY'].shift(1).fillna(0) # 获取前一行的 ΔXY 值
report_data["V(ΔXY)"] = np.where(delta_xy_shift != 0, # 条件:前一行的 ΔXY 不为 0delta_xy_diff / delta_xy_shift, # 条件为 True 时的值:变化速率0 # 条件为 False 时的值:设置为 0
)# 计算 ΔXY 累计变化量 (∑(ΔXY))
report_data["∑(ΔXY)"] = report_data["ΔXY"].cumsum()# 将 NaN 替换为 0
report_data = report_data.fillna(0)# 将数据保留小数点后两位
report_data = report_data.round(2)# 将 DataFrame 转换为列表
data_list = report_data.values.tolist()# 将第一列(索引 0)设置为 0
for row in data_list:row[0] = 0 # 将每一行的第一列设置为 0# 将处理后的列表赋值给 sensor_report["data"]
sensor_report["data"] = data_listlogger.info(f"该台 gnss 设备 {query_para.device_type + '.' + query_para.measurement_id} 的报表数值是: {sensor_report}")return sensor_report
总结
- 修复了
np.where
的错误:确保np.where
的参数完整。 - 解释了
shift
和diff
的区别:shift
用于移动数据。diff
用于计算差值。
- 提供了修复后的完整代码:确保代码逻辑正确,并能正确处理数据。
应用: