如何将 NaN 值绘制为散点图中的间隙

问题描述 投票:0回答:2

我有一个来自 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
python pandas matplotlib nan scatter-plot
2个回答
-1
投票

处理数据中缺失值或 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. 或使用哪种插值方法,都取决于您。或者应该被视为整个模型设计过程中的超参数。


-1
投票

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)
  • xtick 标签的格式将根据自变量的范围而变化。

© www.soinside.com 2019 - 2024. All rights reserved.