突出显示 matplotlib 图形的 pandas 数据框中的异常值
Highlight outliers in pandas dataframe for matplotlib graph
我有 2 个使用 pandas 构建的数据框。当我的数据超出某个参数时,我可以使用布尔索引让 pandas 告诉我。
我想在与原始数据相同的图表上突出显示异常值。我的尝试已在下面的代码中被注释掉,其中 none 行得通。
我的问题是:如何突出显示图表中的异常值?
这是我的代码,用于在我的数据框中查找异常值:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn
#plt.style.use("dark_background")
plt.style.use("seaborn-bright")
x4 = (e[0].time[:47172])
y4 = (e[0].data.f[:47172])
x6 = (t[0].time[:47211])
y6 = (t[0].data.f[:47211])
df4 = pd.DataFrame({'Time': x4, 'Data': y4})
df4['Outlier'] = (df4['Data'] < 2) | (df4['Data'] > 4)
#----This prints out only outliers
df4[df4.Outlier]
df6 = pd.DataFrame({'Time': x4, 'Data': y4})
df6['Outlier'] = (df6['Data'] < 2) | (df6['Data'] > 4)
#----This prints out only outliers
df6[df6.Outlier]
plt.xlabel('Relative Time in Seconds', fontsize=12)
plt.ylabel('Data', fontsize=12)
plt.grid(linestyle = 'dashed')
这只是绘制原始数据:
plt.plot(x4, y4)
plt.plot(x6, y6)
plt.show()
这是我的数据框的示例:
Data Time Outlier
0 0.000 7.343689 True
1 0.000 7.391689 True
2 0.000 7.439689 True
... ... ... ...
47169 2.315 15402.062500 False
47170 0.000 15402.110352 True
47171 0.000 18682.187500 True
[47172 rows x 3 columns]
这些是我的尝试无效:
#fig = plt.figure()
#ax=fig.add_subplot(111)
#ax.plot((df4 < 2), (df4 > 4), color="r")
^这个只是绘制了一条直线,这是不正确的。
#df4.plot((df4['Data'] < 2), (df4['Data'] > 4), color = "r")
^这个打印出的图表在 x 轴而不是时间上有 'True' 和 'False。
我在想类似这样的 for 循环可能会起作用,但我不确定如何实现它。任何 help/feedback 将不胜感激。
for True in 'Outlier':
plt.plot(x4, y4, color='r')
您已经设法只打印异常值,所以现在您可以简单地将它们绘制在正常数据之上,例如:
plt.plot(x4, y4) # Data
plt.plot(x4[df4.Outlier], y4[df4.Outlier], 'r.') # Outlier highlights
plt.plot(x6, y6)
plt.plot(x6[df6.Outlier], y6[df6.Outlier], 'r.')
plt.show()
重要的是使用Boolean series
(例如df4.Outlier
)作为mask
通过索引检索实际异常值值 .在您的非功能性示例中,您正在绘制 mask
本身。
旁注 1: 您可以跳过代码中的整个 pandas 部分(除非您在其他地方需要),然后执行:
mask4 = np.logical_or(y4 < 2, y4 > 4)
mask6 = np.logical_or(y6 < 2, y6 > 4)
plt.plot(x4, y4)
plt.plot(x4[mask4], y4[mask4], 'r.')
plt.plot(x6, y6)
plt.plot(x6[mask6], y6[mask6], 'r.')
plt.show()
旁注 2: 您创建 df6
的行中存在错误:您使用的是 x4
和 y4
x6
和 y6
作为输入。
旁注 3: 与 Boolean masking
相比,循环方法 多 少 effective/elegant,但这里是它是如何工作的(为了学习):
for index,truth_value in enumerate(df4.Outlier):
if truth_value:
plt.plot(x4[index], y4[index], 'r.')
或作为列表理解:
[plt.plot(x4[i], y4[i], 'r.') for i,t in enumerate(df4.Outlier) if t]
我有 2 个使用 pandas 构建的数据框。当我的数据超出某个参数时,我可以使用布尔索引让 pandas 告诉我。 我想在与原始数据相同的图表上突出显示异常值。我的尝试已在下面的代码中被注释掉,其中 none 行得通。 我的问题是:如何突出显示图表中的异常值?
这是我的代码,用于在我的数据框中查找异常值:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn
#plt.style.use("dark_background")
plt.style.use("seaborn-bright")
x4 = (e[0].time[:47172])
y4 = (e[0].data.f[:47172])
x6 = (t[0].time[:47211])
y6 = (t[0].data.f[:47211])
df4 = pd.DataFrame({'Time': x4, 'Data': y4})
df4['Outlier'] = (df4['Data'] < 2) | (df4['Data'] > 4)
#----This prints out only outliers
df4[df4.Outlier]
df6 = pd.DataFrame({'Time': x4, 'Data': y4})
df6['Outlier'] = (df6['Data'] < 2) | (df6['Data'] > 4)
#----This prints out only outliers
df6[df6.Outlier]
plt.xlabel('Relative Time in Seconds', fontsize=12)
plt.ylabel('Data', fontsize=12)
plt.grid(linestyle = 'dashed')
这只是绘制原始数据:
plt.plot(x4, y4)
plt.plot(x6, y6)
plt.show()
这是我的数据框的示例:
Data Time Outlier
0 0.000 7.343689 True
1 0.000 7.391689 True
2 0.000 7.439689 True
... ... ... ...
47169 2.315 15402.062500 False
47170 0.000 15402.110352 True
47171 0.000 18682.187500 True
[47172 rows x 3 columns]
这些是我的尝试无效:
#fig = plt.figure()
#ax=fig.add_subplot(111)
#ax.plot((df4 < 2), (df4 > 4), color="r")
^这个只是绘制了一条直线,这是不正确的。
#df4.plot((df4['Data'] < 2), (df4['Data'] > 4), color = "r")
^这个打印出的图表在 x 轴而不是时间上有 'True' 和 'False。
我在想类似这样的 for 循环可能会起作用,但我不确定如何实现它。任何 help/feedback 将不胜感激。
for True in 'Outlier':
plt.plot(x4, y4, color='r')
您已经设法只打印异常值,所以现在您可以简单地将它们绘制在正常数据之上,例如:
plt.plot(x4, y4) # Data
plt.plot(x4[df4.Outlier], y4[df4.Outlier], 'r.') # Outlier highlights
plt.plot(x6, y6)
plt.plot(x6[df6.Outlier], y6[df6.Outlier], 'r.')
plt.show()
重要的是使用Boolean series
(例如df4.Outlier
)作为mask
通过索引检索实际异常值值 .在您的非功能性示例中,您正在绘制 mask
本身。
旁注 1: 您可以跳过代码中的整个 pandas 部分(除非您在其他地方需要),然后执行:
mask4 = np.logical_or(y4 < 2, y4 > 4)
mask6 = np.logical_or(y6 < 2, y6 > 4)
plt.plot(x4, y4)
plt.plot(x4[mask4], y4[mask4], 'r.')
plt.plot(x6, y6)
plt.plot(x6[mask6], y6[mask6], 'r.')
plt.show()
旁注 2: 您创建 df6
的行中存在错误:您使用的是 x4
和 y4
x6
和 y6
作为输入。
旁注 3: 与 Boolean masking
相比,循环方法 多 少 effective/elegant,但这里是它是如何工作的(为了学习):
for index,truth_value in enumerate(df4.Outlier):
if truth_value:
plt.plot(x4[index], y4[index], 'r.')
或作为列表理解:
[plt.plot(x4[i], y4[i], 'r.') for i,t in enumerate(df4.Outlier) if t]