Как перебрать массив numpy и убрать аномалии? - PullRequest
0 голосов
/ 25 февраля 2019

Я новичок в Python и программировании в целом.Я пытаюсь написать программу, которая выполняет итерацию по определенному массиву пустышек и обнаруживает аномалии в наборе данных (определение аномалии - это любая точка, которая в 3 раза больше стандартного отклонения от среднего значения БЕЗ точки данных).Мне нужно пересчитывать среднее и стандартное отклонение для каждого случая удаления аномальной точки данных.

Я написал приведенный ниже код, но заметил несколько проблем.После того, как цикл повторяется один раз, он утверждает, что значение 160 удаляется, но когда я печатаю new_array, я все равно вижу 160 в массиве.

Кроме того, как я могу пересчитать новое среднее значение при каждом удалении точки данных?Я чувствую, что что-то неправильно расположено внутри цикла for.И, наконец, верно ли мое использование продолжения или оно должно быть в другом месте?

import numpy as np

data_array = np.array([
    99.5697438 ,  94.47019021,  55., 106.86672855,
   102.78730151, 131.85777845,  88.25376895,  96.94439838,
    83.67782174, 115.57993209, 118.97651966,  94.40479467,
    79.63342207,  77.88602065,  96.59145004,  99.50145353,
    97.25980235,  87.72010069, 101.30597215,  87.3110369 ,
   110.0687946 , 104.71504012,  89.34719772, 160.,
   110.61519268, 112.94716398, 104.41867586])

for cell in data_array:
    mean = np.mean(data_array, axis=0)
    sd = np.std(data_array, axis=0)
    lower_anomaly_point = mean - (3 * sd)
    upper_anomaly_point = mean + (3 * sd)
    if cell > upper_anomaly_point or cell < lower_anomaly_point:
        print(str(cell) + 'has been removed.')
        new_array = np.delete(data_array, cell)
        continue 

Ответы [ 3 ]

0 голосов
/ 25 февраля 2019

Этот код не работает для меня.Массив data_array не изменяется, np.delete возвращает новый массив, он не меняет старый.Вы не используете new_array в любом месте кода, вы, вероятно, хотели вычислить среднее значение из new_array. Вторым аргументом для удаления должен быть индекс "указывает, какой подмассив удалить".Вы не можете использовать ячейку.

import numpy as np

data_array = np.array([
    99.5697438 ,  94.47019021,  55., 106.86672855,
   102.78730151, 131.85777845,  88.25376895,  96.94439838,
    83.67782174, 115.57993209, 118.97651966,  94.40479467,
    79.63342207,  77.88602065,  96.59145004,  99.50145353,
    97.25980235,  87.72010069, 101.30597215,  87.3110369 ,
   110.0687946 , 104.71504012,  89.34719772, 160.,
   110.61519268, 112.94716398, 104.41867586])

mean = np.mean(data_array, axis=0)
sd = np.std(data_array, axis=0)
lower_anomaly_point = mean - (3 * sd)
upper_anomaly_point = mean + (3 * sd)
new_array = data_array.copy()
k = 0

for i, cell in enumerate(data_array):
    if cell > upper_anomaly_point or cell < lower_anomaly_point:
        print(str(cell) + 'has been removed.')
        new_array = np.delete(new_array, i - k)
        k += 1

new_array - это data_array без 160. как вы и хотели

0 голосов
/ 25 февраля 2019

Я думаю, что вы должны увидеть Документация Numpy и обратиться к первой строке, где они специально говорят, что она возвращает все элементы, которые не соответствуют arr [obj], это означает, что numpy.delete() работаетна основе индекса.Я бы посоветовал вам отредактировать ваш код, чтобы получить индекс этой ячейки, а затем передать его на np.delete()

Ниже приведен отредактированный код:

import numpy as np

data_array = np.array([99.5697438, 94.47019021, 55.0, 106.86672855, 102.78730151, 131.85777845, 88.25376895, 96.94439838, 83.67782174, 115.57993209, 118.97651966, 94.40479467, 79.63342207, 77.88602065, 96.59145004, 99.50145353, 97.25980235, 87.72010069, 101.30597215, 87.3110369, 110.0687946, 104.71504012, 89.34719772, 160.0, 110.61519268, 112.94716398, 104.41867586])
print(data_array)
for cell in data_array:
    mean = np.mean(data_array, axis=0)
    sd = np.std(data_array, axis=0)
    lower_anomaly_point = mean - (3 * sd)
    upper_anomaly_point = mean + (3 * sd)
    if cell > upper_anomaly_point or cell < lower_anomaly_point:
        print(str(cell) + 'has been removed.')
        index=np.where(data_array==cell)
        new_array = np.delete(data_array, obj=index)
        continue 
0 голосов
/ 25 февраля 2019

Как @damagedcoda говорит, что ваша основная ошибка в том, что вы должны использовать вместо значения index индекс, но у вас возникнут новые проблемы, если вы будете пересчитывать lower_anomaly_point и upper_anomaly_point внутри цикла.Поэтому я рекомендую вам попробовать np.where для решения вашей задачи:

import numpy as np

data_array = np.array([
    99.5697438 ,  94.47019021,  55., 106.86672855,
   102.78730151, 131.85777845,  88.25376895,  96.94439838,
    83.67782174, 115.57993209, 118.97651966,  94.40479467,
    79.63342207,  77.88602065,  96.59145004,  99.50145353,
    97.25980235,  87.72010069, 101.30597215,  87.3110369 ,
   110.0687946 , 104.71504012,  89.34719772, 160.,
   110.61519268, 112.94716398, 104.41867586])

mean = np.mean(data_array, axis=0)
sd = np.std(data_array, axis=0)
lower_anomaly_point = mean - (3 * sd)
upper_anomaly_point = mean + (3 * sd)

data_array = data_array[
    np.where(
        (upper_anomaly_point > data_array) & (data_array > lower_anomaly_point)
    )]

и результат:

array([ 99.5697438 ,  94.47019021,  55.        , 106.86672855,
       102.78730151, 131.85777845,  88.25376895,  96.94439838,
        83.67782174, 115.57993209, 118.97651966,  94.40479467,
        79.63342207,  77.88602065,  96.59145004,  99.50145353,
        97.25980235,  87.72010069, 101.30597215,  87.3110369 ,
       110.0687946 , 104.71504012,  89.34719772, 110.61519268,
       112.94716398, 104.41867586])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...