Применить df.where к выборочным столбцам в пандах, чтобы удалить выбросы в наборе данных смешанного типа - PullRequest
0 голосов
/ 06 октября 2019

Новичок в Python и pandas настраивает конвейер очистки данных для подготовки к машинному обучению. Я хотел бы идентифицировать и удалить выбросы и заменить на месте (например) среднее арифметическое.

df был очищен, так что столбец # 1 строк ('Identifiers') был установлен как индекс (type = object), а остальные столбцы являются чисто числовыми и установлены как float. Игрушечная неопознанная версия ввода df:

Identifiers        foo  categorical   bar  score1  score2  score3
0         bob   9.717501          1.0   2.0    34.0     4.0    44.0
1       carol  15.940285          0.0   6.0    65.0     3.0    46.0
2       alice  13.938485          0.0  32.0    55.0    18.0    68.0
3         jim   8.918572          0.0  15.0    71.0     5.0    50.0
4      nathan   9.698413          0.0   4.0    36.0    10.0    48.0

Следующий код успешно выполняется:

for col in df_pheno:
s = df_pheno.mean(axis = 0)
q = df_pheno.std (axis = 0)
r = s + (3 * q)
if col == 'Identifiers':
    continue
elif col != 'Identifiers':
    for i, row_value in df_pheno[col].iteritems():
        if row_value > r.loc[col]:
            row_value = df_pheno.replace(row_value,s.loc[col],inplace = True)
        elif row_value <= r.loc[col]:
            continue

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

Identifiers        foo  categorical   bar  score1  score2  score3
0         bob   9.717501          0.2   2.0    34.0     4.0    44.0
1       carol  11.642651          0.0   6.0    52.2     3.0    46.0
2       alice  11.642651          0.0  11.8    52.2     8.0    51.2
3         jim   8.918572          0.0  11.8    52.2     5.0    50.0
4      nathan   9.698413          0.0   4.0    36.0     8.0    48.0

Я хотел бы посмотреть, не ускоряет ли df.where операцию, но в различных перестановках я тоже не могу a)заставить его игнорировать столбец «Идентификаторы» или b) ввести значение, отличное от NaN. По причинам, связанным со следующим шагом в конвейере, я бы предпочел не вставлять NaN, а затем вводить значения, отличные от NaN - если это возможно. Пример усилий / проблем:

for col in df_pheno:
s = df_pheno.mean(axis = 0)
q = df_pheno.std (axis = 0)
r = s + (3 * q)
if col == 'Identifiers':
    continue
elif col != 'Identifiers':
    df_pheno.where(df_pheno > r, s, inplace=True, axis=1)

Ошибка типа: невозможно выполнить булеву настройку на месте для смешанных типов со значением, отличным от np.nan

И альтернативно:

for col in df_pheno:
s = df_pheno.mean(axis = 0)
q = df_pheno.std (axis = 0)
r = s + (3 * q)
if col == 'Identifiers':
    continue
elif col != 'Identifiers':
    df_pheno[col].where(df_pheno[col] > r, s[col], inplace=True, axis=1)

ValueError: Может сравнивать только идентично помеченные объекты Series

. Любая помощь приветствуется.

1 Ответ

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

Ваша проблема в том, что ряды std (s), mean и r не имеют значения для идентификаторов, однако DataFrame имеет. Вот почему я собираюсь использовать set_index('Identifiers'), и когда я закончу работу reset_index().

, проконсультируйтесь здесь:

DataFrame.set_index y DataFrame. reset_index


Я думаю, вам нужно только:

df=df_pheno.set_index('Identifiers')
m=df.mean()
s=df.std()
r=m+3*s

Теперь примените mask с r , м или с :

df.mask(df>m,m,axis=1).reset_index()

Выход:

  Identifiers        foo  categorical  bar  score1  score2  score3
0         bob  10.723134          0.0  1.0    40.0     3.0    48.0
1       carol  11.567761          0.2  0.0    34.0     2.0    43.0
2       alice  11.567761          0.0  9.2    50.4     7.6    53.8
3         jim  10.793862          0.0  9.2    50.4     3.0    48.0
4      nathan   9.633013          0.0  2.0    44.0     7.6    53.8

или

df.mask(df>s,s,axis=1).reset_index()

или

df.mask(df>r,r,axis=1).reset_index()
...