我有一个来自 Pandas 数据帧的包含六个子图控制图的图,当前按索引绘制,我想根据日期时间值绘制它们。原始数据(来自 XML 文件)包含空白值,以“-”形式给出,我将其转换为 numpy NaN:
df[y[0]].replace({'-': np.nan}, inplace =True)
我不能使用零,因为我需要对它们运行统计数据,包括移动范围计算,用于创建控制限制。结果是真正的空白,而不是零。
索引输出效果非常好:
我想根据 df 中的时间戳值(非常规)绘制相同的数据,但 NaN 值导致错误
x and y must be the same size
,因为一旦删除 NaN,时间戳的数量就多于值的数量。
错误发生在(毫不奇怪)
df.plot.scatter(y = y[0], ax=axes[0], x = 'TIMESTAMP')
由于 NaN 值不会出现在所有六个子图中的同一时间点,因此保持时间轴并为 NaN 值留出间隙非常重要;我不想只删除整行,因为在任何给定时间通常只有一个具有五个有效点的 NaN。
样本数据:
data = {'TIMESTAMP': ['01/07/2023 08:04:11', '01/07/2023 08:04:37', '01/07/2023 08:04:53', '01/07/2023 08:05:06', '01/07/2023 08:05:18', '01/07/2023 08:05:29', '01/07/2023 08:05:40', '01/07/2023 08:05:50', '01/07/2023 08:06:01', '01/07/2023 08:06:12', '01/07/2023 08:06:22', '01/07/2023 08:06:33', '01/07/2023 08:06:43'],
'y1': ['107.08', '107.54', '107.18', '-', '106.92', '107.16', '107.46', '107.68', '107.84', '107.88', '108.1', '108.06', '108.2'],
'y2': [107.12, 107.0, 107.92, 107.78, 106.96, 107.36, 107.58, 107.66, 107.92, 107.8, 107.94, 108.2, 108.12],
'y3': ['107.66', '107.16', '106.92', '108.14', '106.96', '-', '107.54', '107.58', '107.72', '107.82', '107.96', '108.04', '108.12'],
'y4': ['107.48', '107.6', '107.82', '107.78', '107.02', '-', '107.46', '107.48', '107.76', '107.82', '107.88', '108.02', '108.08'],
'y5': ['107.38', '107.6', '107.6', '107.72', '107.48', '107.82', '107.9', '108.12', '108.22', '-', '108.7', '107.98', '107.94'],
'y6': [107.44, 107.62, 107.48, 107.56, 107.46, 107.72, 107.82, 108.08, 108.06, 108.2, 108.18, 108.36, 108.46]}
df = pd.DataFrame(data)
TIMESTAMP y1 y2 y3 y4 y5 y6
0 01/07/2023 08:04:11 107.08 107.12 107.66 107.48 107.38 107.44
1 01/07/2023 08:04:37 107.54 107.00 107.16 107.6 107.6 107.62
2 01/07/2023 08:04:53 107.18 107.92 106.92 107.82 107.6 107.48
3 01/07/2023 08:05:06 - 107.78 108.14 107.78 107.72 107.56
4 01/07/2023 08:05:18 106.92 106.96 106.96 107.02 107.48 107.46
5 01/07/2023 08:05:29 107.16 107.36 - - 107.82 107.72
6 01/07/2023 08:05:40 107.46 107.58 107.54 107.46 107.9 107.82
7 01/07/2023 08:05:50 107.68 107.66 107.58 107.48 108.12 108.08
8 01/07/2023 08:06:01 107.84 107.92 107.72 107.76 108.22 108.06
9 01/07/2023 08:06:12 107.88 107.80 107.82 107.82 - 108.20
10 01/07/2023 08:06:22 108.1 107.94 107.96 107.88 108.7 108.18
11 01/07/2023 08:06:33 108.06 108.20 108.04 108.02 107.98 108.36
12 01/07/2023 08:06:43 108.2 108.12 108.12 108.08 107.94 108.46
处理数据中缺失值或 NaN(非数字)值是一种 数据预处理的重要步骤。特别是当您下一步尝试进行移动极差计算时。
因此,首先我建议您不要尝试将这个地方留空以用于可视化目的(如果您愿意,您可以打印白点),但已经考虑您的下一步以及您需要如何处理它们才能进行计算 - 否则你只会将你的问题向前推进一步。对于可视化,您可以相应地明显标记(点的颜色或形状)更改的 NaN 值,因此仍然可以看出这些值已被近似,并且不是来自您的主要传感器或数据源。
1。全局插补
将 NaN 值替换为相应特征的平均值、中值或最频繁值。这是一种简单快速的填充缺失值的方法,尤其是对于数字特征。
import pandas as pd
# Sample DataFrame with NaN values
data = {'column_name': [1, 2, np.nan, 4, 5]}
df = pd.DataFrame(data)
# Mean imputation for 'column_name'
mean_value = df['column_name'].mean() #3
df['column_name'].fillna(mean_value, inplace=True)
2。局部插值
使用插值技术(例如线性插值)根据周围数据点估计缺失值。这通常用于时间序列数据。
# Sample DataFrame with NaN values
data = {'column_name': [1, 2, np.nan, 4, 5]}
df = pd.DataFrame(data)
# Interpolation for 'column_name'
df['column_name'].interpolate(method='linear', inplace=True) # 3
您最了解您的数据,因此无论是 1. 还是 2. 或使用哪种插值方法,都取决于您。或者应该被视为整个模型设计过程中的超参数。
OP 正在针对数据框
index
进行绘图,但希望针对 'TIMESTAMP'
列绘制子图中的每一列,并且不想填充 NaN
。
任何带有
'-'
的列都会导入为 object dtype
,而不是 float
,因此在用 np.nan
替换值后,这些列必须转换为 float dtype
。
当前代码意味着采用迭代方法来清理数据和绘图,并且 OP 状态
NaNs
被删除,这会导致与 'TIMESTAMP'
列的长度不匹配,并导致 x and y must be the same size
。
带有
NaN
的列将毫无问题地针对 'TIMESTAMP'
列进行绘图,如以下代码所示,并且根据 OP 中的要求,将有一个与 NaN
位置相对应的空格。
已在
python 3.11.5
、pandas 2.1.0
、matplotlib 3.7.2
进行测试
# convert TIMESTAMP to a datatime
df.TIMESTAMP = pd.to_datetime(df.TIMESTAMP)
# replace all '-' with np.nan
df.replace({'-': np.nan}, inplace=True)
# a list of the columns to plot on y
cols = df.columns[1:]
# convert the columns to floats
df[cols] = df[cols].astype(float)
# create the figure and axes
fig, axes = plt.subplots(nrows=len(cols), figsize=(8, 8), tight_layout=True, sharex=True)
# iterate through each column to plot on one of the subplots
for ax, col in zip(axes, cols):
# plot the dataframe column
df.plot(kind='scatter', x='TIMESTAMP', y=col, ax=ax)