突出显示matplotlib图的pandas数据帧中的异常值

时间:2017-08-07 15:42:30

标签: python pandas matplotlib dataframe

我有2个使用pandas构建的数据帧。我可以通过使用布尔索引让我的数据超出某个参数时让大熊猫告诉我。 我想在原始数据的同一图表上突出显示我的异常值。我的尝试已经在下面的代码中被注释掉,但没有一个能够工作。 我的问题是:如何在图表中突出显示异常值?

这是我的代码,用于查找数据框中的异常值:

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 True in 'Outlier':
    plt.plot(x4, y4, color='r')

1 个答案:

答案 0 :(得分:2)

您已设法仅打印异常值,因此现在您可以在普通数据的基础上绘制它们,例如:

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的行中出现错误:您使用的是x4y4,而不是x6 }和y6作为输入。

附注3:Boolean masking相比,循环方法 效率低劣/优雅,但这是如何工作的(为了学习) ):

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]