Избавление от посторонних строк в нескольких столбцах панд данных
У меня есть фрейм данных панд со многими столбцами (>100). Я стандартизировал все значения столбцов, поэтому каждый столбец центрируется на 0 (они имеют среднее значение 0 и стандартное отклонение 1). Я хочу избавиться от всех строк, которые ниже -2 и выше 2 с учетом всех столбцов. Имея это в виду, допустим, в первом столбце строки 2,3,4 являются выбросами, а во втором столбце строки 3,4,5,6 являются выбросами. Тогда я бы хотел избавиться от строк [2,3,4,5,6].
То, что я пытаюсь сделать, это использовать цикл for для передачи для каждого столбца, собирать индекс строки, которые являются выбросами, и сохранять их в списке. В конце у меня есть список, содержащий списки с индексом строки каждого столбца. Я получаю уникальные значения, чтобы получить индекс строки, от которого я должен избавиться. Моя проблема в том, что я не знаю, как разделить фрейм данных, чтобы он не содержал эти строки. Я думал об использовании оператора%in%, но он не допускает формат # list в списке #. Я показываю мой код ниже.
### Getting rid of the outliers
'''
We are going to get rid of the outliers who are outside the range of -2 to 2.
'''
aux_features = features_scaled.values
n_cols = aux_features.shape[1]
n_rows = aux_features.shape[0]
outliers_index = []
for i in range(n_cols):
variable = aux_features[:,i] # We take one column at a time
condition = (variable < -2) | (variable > 2) # We stablish the condition for the outliers
index = np.where(condition)
outliers_index.append(index)
outliers = [j for i in outliers_index for j in i]
outliers_2 = np.array([j for i in outliers for j in i])
unique_index = list(np.unique(outliers_2)) # This is the final list with all the index that contain outliers.
total_index = list(range(n_rows))
aux = (total_index in unique_index)
outliers_2 содержит список со всеми индексами строк (включая повторение), затем в unique_index я получаю только уникальные значения, поэтому я заканчиваю всеми индексами строк, которые имеют выбросы. Я застрял в этой части. Если кто-то знает, как его завершить, или лучше представляете, как избавиться от этих выбросов (я думаю, мой метод будет очень трудоемким для действительно больших наборов данных)
1 ответ
df = pd.DataFrame(np.random.standard_normal(size=(1000, 5))) # example data
cleaned = df[~(np.abs(df) > 2).any(1)]
Объяснение:
Фильтровать информационный кадр для значений выше и ниже 2. Возвращает информационный кадр, содержащий логические выражения:
np.abs(df) > 2
Проверьте, содержит ли строка выбросы. Значение true для каждой строки, в которой существует выброс:
(np.abs(df) > 2).any(1)
Наконец, выберите все строки без выброса, используя ~
оператор:
df[~(np.abs(df) > 2).any(1)]