Маркировка выбросов на графике рассеяния - PullRequest
2 голосов
/ 03 октября 2019

У меня есть кадр данных, который выглядит следующим образом:

 print(df.head(10))

 day         CO2
   1  549.500000
   2  663.541667
   3  830.416667
   4  799.695652
   5  813.850000
   6  769.583333
   7  681.941176
   8  653.333333
   9  845.666667
  10  436.086957

Затем я использую следующую функцию и строки кода, чтобы получить выбросы из столбца CO2:

def estimate_gaussian(dataset):

    mu = np.mean(dataset)#moyenne cf mu
    sigma = np.std(dataset)#écart_type/standard deviation
    limit = sigma * 1.5

    min_threshold = mu - limit
    max_threshold = mu + limit

    return mu, sigma, min_threshold, max_threshold

mu, sigma, min_threshold, max_threshold = estimate_gaussian(df['CO2'].values)


condition1 = (dataset < min_threshold)
condition2 = (dataset > max_threshold)

outliers1 = np.extract(condition1, dataset)
outliers2 = np.extract(condition2, dataset)

outliers = np.concatenate((outliers1, outliers2), axis=0)

Какойдает мне следующий результат:

print(outliers)

[830.41666667 799.69565217 813.85       769.58333333 845.66666667]

Теперь я хотел бы отметить эти выбросы красным цветом на графике рассеяния.

Ниже приведен код, который я использовал длявыделите один выброс в красном на графике рассеяния, но я не могу найти способ сделать это для каждого элемента списка выбросов, который является numpy.ndarray:

y = df['CO2']

x = df['day']

col = np.where(x<0,'k',np.where(y<845.66666667,'b','r'))

plt.scatter(x, y, c=col, s=5, linewidth=3)
plt.show()

Вот что я получу, но я быкак тот же результат всех выбросов. Не могли бы вы помочь мне?

https://ibb.co/Ns9V7Zz

Ответы [ 5 ]

1 голос
/ 03 октября 2019

Вот одно быстрое решение:

Я воссоздаю то, что вы уже должны начать. Вы только поделились заголовком своего фрейма данных, но как бы то ни было, я просто вставил несколько случайных выбросов. Похоже, что ваша функция "valu_gaussian ()" может когда-либо возвращать только два выброса?

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame([549.500000,
                50.0000000,
                830.416667,
                799.695652,
                1200.00000,
                769.583333,
                681.941176,
                1300.00000,
                845.666667,
                436.086957], 
                columns=['CO2'],
                index=list(range(1,11)))

def estimate_gaussian(dataset):

    mu = np.mean(dataset) # moyenne cf mu
    sigma = np.std(dataset) # écart_type/standard deviation
    limit = sigma * 1.5

    min_threshold = mu - limit
    max_threshold = mu + limit

    return mu, sigma, min_threshold, max_threshold

mu, sigma, min_threshold, max_threshold = estimate_gaussian(df.values)

condition1 = (df < min_threshold)
condition2 = (df > max_threshold)

outliers1 = np.extract(condition1, df)
outliers2 = np.extract(condition2, df)

outliers = np.concatenate((outliers1, outliers2), axis=0)

Тогда мы построим график:

df_red = df[df.values==outliers]

plt.scatter(df.index,df.values)
plt.scatter(df_red.index,df_red.values,c='red')
plt.show()

enter image description here

Дайте мне знать, если вам нужно что-то более нюансированное!

0 голосов
/ 03 октября 2019

Существует несколько способов, одним из которых может быть создание последовательности цветов на основе вашего состояния и передача ее параметру c.

df = pd.DataFrame({'CO2': {0: 549.5,
  1: 663.54166699999996,
  2: 830.41666699999996,
  3: 799.695652,
  4: 813.85000000000002,
  5: 769.58333300000004,
  6: 681.94117599999993,
  7: 653.33333300000004,
  8: 845.66666699999996,
  9: 436.08695700000004},
 'day': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10}})

In [11]: colors = ['r' if n<750 else 'b' for n in df['CO2']]

In [12]: colors
Out[12]: ['r', 'r', 'b', 'b', 'b', 'b', 'r', 'r', 'b', 'r']

In [13]: plt.scatter(df['day'],df['CO2'],c=colors)

Или используйте np.where для создания последовательности

In [14]: colors = np.where(df['CO2'] < 750, 'r', 'b')
0 голосов
/ 03 октября 2019

Вы можете создать дополнительный столбец (логический), в котором вы определяете, является ли точка выбросом (True) или нет (False), а затем работать с двумя точечными диаграммами:

df["outlier"] = # your boolean np array goes in here
plt.scatter[df.loc[df["outlier"], "day"], df.loc[df["outlier"], "CO2"], color="k"]
plt.scatter[df.loc[~df["outlier"], "day"], df.loc[~df["outlier"], "CO2"], color="r"]
0 голосов
/ 03 октября 2019

Я не уверен, что идея вашего списка col, но вы можете заменить col на

col = ['red' if yy in list(outliers) else 'blue' for yy in y] 
0 голосов
/ 03 октября 2019

Возможно, не самое эффективное решение, но я чувствую, что проще звонить plt.scatter несколько раз, пропуская одну пару ху каждый раз. Поскольку мы никогда не вызываем новую фигуру (например, используя plt.figure()), каждая пара xy строится на одной фигуре.

Затем в каждой итерации нам просто нужно проверить, является ли значение y выбросом. Если это так, мы изменим аргумент ключевого слова color при вызове plt.scatter.

Попробуйте:

mu, sigma, min_threshold, max_threshold = estimate_gaussian(df['CO2'].values)

xs = df['day']
ys = df['CO2']

for x, y in zip(xs, ys):
    color = 'blue'  # non-outlier color
    if not min_threshold <= y <= max_threshold:  # condition for being an outlier
        color = 'red'  # outlier color
    plt.scatter(x, y, color=color)
plt.show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...