您可以删除NaN
首先从数据中提取 s,然后绘制过滤后的数据。
为此,您可以首先找到NaN
s using np.isnan(data) https://docs.scipy.org/doc/numpy/reference/generated/numpy.isnan.html,然后使用该布尔数组执行按位反转~:按位取反运算符 https://docs.python.org/3/library/operator.html#mapping-operators-to-functions。用它来索引数据数组,然后过滤掉NaN
s.
filtered_data = data[~np.isnan(data)]
在一个完整的例子中(改编自here https://matplotlib.org/stable/gallery/pyplots/boxplot_demo_pyplot.html)
测试于python 3.10
, matplotlib 3.5.1
, seaborn 0.11.2
, numpy 1.21.5
, pandas 1.4.2
对于一维数据:
import matplotlib.pyplot as plt
import numpy as np
# fake up some data
np.random.seed(2022) # so the same data is created each time
spread = np.random.rand(50) * 100
center = np.ones(25) * 50
flier_high = np.random.rand(10) * 100 + 100
flier_low = np.random.rand(10) * -100
data = np.concatenate((spread, center, flier_high, flier_low), 0)
# Add a NaN
data[40] = np.NaN
# Filter data using np.isnan
filtered_data = data[~np.isnan(data)]
# basic plot
plt.boxplot(filtered_data)
plt.show()
对于二维数据:
对于 2D 数据,不能简单地使用上面的掩码,因为这样数据数组的每一列都会有不同的长度。相反,我们可以创建一个列表,列表中的每一项都是数据数组每列的过滤数据。
列表理解可以在一行中完成此操作:[d[m] for d, m in zip(data.T, mask.T)]
import matplotlib.pyplot as plt
import numpy as np
# fake up some data
np.random.seed(2022) # so the same data is created each time
spread = np.random.rand(50) * 100
center = np.ones(25) * 50
flier_high = np.random.rand(10) * 100 + 100
flier_low = np.random.rand(10) * -100
data = np.concatenate((spread, center, flier_high, flier_low), 0)
data = np.column_stack((data, data * 2., data + 20.))
# Add a NaN
data[30, 0] = np.NaN
data[20, 1] = np.NaN
# Filter data using np.isnan
mask = ~np.isnan(data)
filtered_data = [d[m] for d, m in zip(data.T, mask.T)]
# basic plot
plt.boxplot(filtered_data)
plt.show()
我将把它作为练习留给读者,将其扩展到 3 个或更多维度,但您已经明白了。
上面的解决方案是如何使用matplotlib
独自的。其他替代方案(使用matplotlib
在引擎盖下)都可以使用内置此行为,因此无需自己过滤数据。
- Use
seaborn
,这是一个高级 APImatplotlib
. seaborn.boxplot https://seaborn.pydata.org/generated/seaborn.boxplot.html过滤器NaN
在引擎盖下。
import seaborn as sns
sns.boxplot(data=data)
1D
2D
- Use
pandas
. NaN
如果从以下位置绘制也会被忽略df.plot(kind='box') https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.plot.html for pandas
,它使用matplotlib
作为默认的绘图后端。
import pandas as pd
df = pd.DataFrame(data)
df.plot(kind='box')
1D
2D