gpt4 book ai didi

python - 如何在 matplotlib 中绘制和使用 NaN 值

转载 作者:IT老高 更新时间:2023-10-28 20:54:15 27 4
gpt4 key购买 nike

我有由多列组成的每小时数据。第一列是日期(date_log),其余列包含不同的样本点。问题是采样点使用不同的时间记录,即使是每小时,所以每列至少有几个 NaN。如果我使用第一个代码进行绘制,它可以很好地工作,但我希望在一天左右没有记录器数据的情况下存在间隙,并且不希望将这些点连接起来。如果我使用第二个代码,我可以看到差距,但由于 NaN 点,数据点没有得到连接。在下面的示例中,我只绘制了前三列。

当存在像蓝点这样的大差距时 (01/06-01/07/2015),我希望有一个差距,然后将积分加入。第二个例子没有加入点。我喜欢第一个图表,但是当 24 小时日期范围内没有样本数据点等时,我想像第二种方法一样创建间隙。将丢失的数据点留下更长的时间作为间隙。

有什么解决办法吗?谢谢

方法一:

Log_1a_mask = np.isfinite(Log_1a) # Log_1a is column 2 data points
Log_1b_mask = np.isfinite(Log_1b) # Log_1b is column 3 data points

plt.plot_date(date_log[Log_1a_mask], Log_1a[Log_1a_mask], linestyle='-', marker='',color='r',)
plt.plot_date(date_log[Log_1b_mask], Log_1b[Log_1b_mask], linestyle='-', marker='', color='b')
plt.show()

方法二:

plt.plot_date(date_log, Log_1a, ‘-r*’, markersize=2, markeredgewidth=0, color=’r’) # Log_1a contains raw data with NaN
plt.plot_date(date_log, Log_1b, ‘-r*’, markersize=2, markeredgewidth=0, color=’r’) # Log_1a contains raw data with NaN
plt.show()

方法一输出: enter image description here

方法 2 输出: enter image description here

最佳答案

如果我对您的理解正确,您有一个数据集,其中包含许多您想要填补的小空白(单个 NaN)以及您不想填补的较大空白。

使用 pandas “向前填补”空白

一种选择是使用具有有限填充值的 pandas fillna

作为一个简单的例子来说明它是如何工作的:

In [1]: import pandas as pd; import numpy as np

In [2]: x = pd.Series([1, np.nan, 2, np.nan, np.nan, 3, np.nan, np.nan, np.nan, 4])

In [3]: x.fillna(method='ffill', limit=1)
Out[3]:
0 1
1 1
2 2
3 2
4 NaN
5 3
6 3
7 NaN
8 NaN
9 4
dtype: float64

In [4]: x.fillna(method='ffill', limit=2)
Out[4]:
0 1
1 1
2 2
3 2
4 2
5 3
6 3
7 3
8 NaN
9 4
dtype: float64

作为将其用于类似于您的情况的示例:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1977)

x = np.random.normal(0, 1, 1000).cumsum()

# Set every third value to NaN
x[::3] = np.nan

# Set a few bigger gaps...
x[20:100], x[200:300], x[400:450] = np.nan, np.nan, np.nan

# Use pandas with a limited forward fill
# You may want to adjust the `limit` here. This will fill 2 nan gaps.
filled = pd.Series(x).fillna(limit=2, method='ffill')

# Let's plot the results
fig, axes = plt.subplots(nrows=2, sharex=True)
axes[0].plot(x, color='lightblue')
axes[1].plot(filled, color='lightblue')

axes[0].set(ylabel='Original Data')
axes[1].set(ylabel='Filled Data')

plt.show()

enter image description here

使用 numpy 插入间隙

或者,我们可以只使用 numpy 来做到这一点。可以(并且更有效)执行与上述 pandas 方法相同的“前向填充”,但我将展示另一种方法,为您提供更多选择,而不仅仅是重复值。

我们可以对间隙中的值进行线性插值,而不是通过“间隙”重复上一个值。这在计算上效率较低(我将通过在任何地方进行插值来使其效率更低),但对于大多数数据集,您不会注意到重大差异。

作为一个例子,让我们定义一个 interpolate_gaps 函数:

def interpolate_gaps(values, limit=None):
"""
Fill gaps using linear interpolation, optionally only fill gaps up to a
size of `limit`.
"""
values = np.asarray(values)
i = np.arange(values.size)
valid = np.isfinite(values)
filled = np.interp(i, i[valid], values[valid])

if limit is not None:
invalid = ~valid
for n in range(1, limit+1):
invalid[:-n] &= invalid[n:]
filled[invalid] = np.nan

return filled

请注意,我们将获得插值,与之前的 pandas 版本不同:

In [11]: values = [1, np.nan, 2, np.nan, np.nan, 3, np.nan, np.nan, np.nan, 4]

In [12]: interpolate_gaps(values, limit=1)
Out[12]:
array([ 1. , 1.5 , 2. , nan, 2.66666667,
3. , nan, nan, 3.75 , 4. ])

在绘图示例中,如果我们替换行:

filled = pd.Series(x).fillna(limit=2, method='ffill')

与:

filled = interpolate_gaps(x, limit=2)

我们将得到一个视觉上相同的图:

enter image description here

作为一个完整的独立示例:

import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1977)

def interpolate_gaps(values, limit=None):
"""
Fill gaps using linear interpolation, optionally only fill gaps up to a
size of `limit`.
"""
values = np.asarray(values)
i = np.arange(values.size)
valid = np.isfinite(values)
filled = np.interp(i, i[valid], values[valid])

if limit is not None:
invalid = ~valid
for n in range(1, limit+1):
invalid[:-n] &= invalid[n:]
filled[invalid] = np.nan

return filled

x = np.random.normal(0, 1, 1000).cumsum()

# Set every third value to NaN
x[::3] = np.nan

# Set a few bigger gaps...
x[20:100], x[200:300], x[400:450] = np.nan, np.nan, np.nan

# Interpolate small gaps using numpy
filled = interpolate_gaps(x, limit=2)

# Let's plot the results
fig, axes = plt.subplots(nrows=2, sharex=True)
axes[0].plot(x, color='lightblue')
axes[1].plot(filled, color='lightblue')

axes[0].set(ylabel='Original Data')
axes[1].set(ylabel='Filled Data')

plt.show()

注意:我最初完全误读了这个问题。请参阅我的原始答案的版本历史记录。

关于python - 如何在 matplotlib 中绘制和使用 NaN 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36455083/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com