Найти столбцы в пределах определенного процентиля DataFrame

Имея многостолбцовый фрейм данных, меня интересует, как сохранить/получить часть фрейма данных, которая находится между 25-м и 75-м процентилями для каждого столбца? Мне нужно удалить строки (которые являются просто временными шагами), которые имеют значения за пределами диапазона 25-75 процентилей.

import numpy as np
import pandas as pd   

df1 = pd.DataFrame({
       '400.0': [13.909261, 13.758734, 13.513627, 13.095409, 13.628918, 12.782643, 13.278548, 13.160153, 12.155895, 12.152373, 12.147820, 13.023997, 15.010729, 13.006050, 13.002356],
       '401.0': [14.581624, 14.173803, 13.757856, 14.223524, 14.695623, 13.818065, 13.300235, 13.173674, 14.145402, 14.144456, 13.142969, 13.022471, 14.010802, 14.006181, 14.002641],
       '402.0': [15.253988, 15.588872, 15.002085, 15.351638, 14.762327, 14.853486, 15.321922, 14.187195, 15.134910, 15.136539, 15.138118, 15.020945, 15.010875, 15.006313, 15.002927],
       '403.0': [15.633908, 14.833914, 15.146499, 15.431543, 15.798185, 14.874350, 14.333470, 14.192128, 15.130119, 15.134795, 15.136049, 15.019307, 15.012037, 15.006674, 15.003002],
       })

Я ожидаю увидеть меньшее количество строк, поэтому мне придется исключить ряд измерений, которые действуют как выбросы временных рядов.

введите здесь описание изображения

Это из исходного набора данных, где по оси X показаны строки. Поэтому мне нужно как-то удалить этот блоб, установив критерии процентиля

В конце концов, я бы взял самые строгие критерии, чтобы применить их ко всему фрейму данных.


person PEBKAC    schedule 28.09.2018    source источник
comment
Вы хотите сохранить строки, которые попадают между 25-м и 75-м процентилем определенного столбца? Как определить, попадает ли вся строка в эти процентили?   -  person sacuL    schedule 28.09.2018
comment
Я обновлю пост, хороший вопрос. Я имею в виду процентили в каждом столбце, точно!   -  person PEBKAC    schedule 28.09.2018
comment
В пределах 25-го и 75-го процентиля какого столбца? И если это все столбцы, вы также имеете в виду глубину (поскольку он имеет другой тип метки для всех других столбцов), я подозреваю, что вы могли бы иметь в виду сохранить значение этого столбца, ГДЕ другие находятся в пределах, но если эти ограничения применяются для всех остальных столбцов, что тогда должно произойти? Краткая версия - что вы ожидаете увидеть?   -  person Ymareth    schedule 28.09.2018
comment
Извините, я обновил сообщение: я ожидаю увидеть меньшее количество строк, поэтому мне придется исключить ряд измерений, которые действуют как выбросы временных рядов. Столбец глубины здесь устарел, каждый из остальных должен попадать в процентиль 25-75, поэтому, думаю, в конце я бы взял самые строгие критерии, чтобы применить его ко всему фрейму данных.   -  person PEBKAC    schedule 28.09.2018
comment
Я думаю, что путаница связана с тем, что строка будет иметь несколько значений. Каждое из этих значений может быть помечено отдельно как выброс для соответствующего столбца. Итак, вы хотите удалить строку, если any значений находятся за пределами, или только если all. Или, возможно, установить порог?   -  person ALollz    schedule 28.09.2018
comment
Да, именно так, допустим, у меня есть 1000 строк, и определенная часть временного ряда выполняет какую-то случайную работу, и это отражается на более низких значениях для этого набора строк. Так что мне нужно обнаружить это. Я прикреплю график исходного (не сжатого) фрейма данных, чтобы вы могли видеть, о чем я говорю.   -  person PEBKAC    schedule 28.09.2018


Ответы (2)


Я не уверен на 100%, что это то, что вы хотите, но IIUC, вы можете создать маску, а затем применить ее к своему фрейму данных.

df1[df1.apply(lambda x: x.between(x.quantile(.25), x.quantile(.75))).all(1)]

       400.0      401.0      402.0      403.0
8  12.155895  14.145402  15.134910  15.130119
9  12.152373  14.144456  15.136539  15.134795

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

Если вместо этого вы хотите удалить только те строки, которые содержат все значения, выходящие за пределы вашего диапазона, вы можете использовать:

df1[df1.apply(lambda x: x.between(x.quantile(.25), x.quantile(.75))).any(1)]

        400.0      401.0      402.0      403.0
2   13.513627  13.757856  15.002085  15.146499
3   13.095409  14.223524  15.351638  15.431543
5   12.782643  13.818065  14.853486  14.874350
6   13.278548  13.300235  15.321922  14.333470
7   13.160153  13.173674  14.187195  14.192128
8   12.155895  14.145402  15.134910  15.130119
9   12.152373  14.144456  15.136539  15.134795
10  12.147820  13.142969  15.138118  15.136049
11  13.023997  13.022471  15.020945  15.019307
12   0.010729  14.010802  15.010875  15.012037
13   0.006050  14.006181  15.006313  15.006674
14   0.002356  14.002641  15.002927  15.003002

Строки сохраняются здесь, если какое-либо из значений в любом столбце попадает в диапазон процентилей в соответствующем столбце.

person sacuL    schedule 28.09.2018

Здесь будет намного быстрее работать с базовыми массивами numpy:

a = df1.values
q1 = np.quantile(a, q=0.25, axis=0)
q2 = np.quantile(a, q=0.75, axis=0)

mask = ((q1 < a) & (a < q2)).all(1)

df1[mask]

       400.0      401.0      402.0      403.0
8  12.155895  14.145402  15.134910  15.130119
9  12.152373  14.144456  15.136539  15.134795

Invert the mask (df[~mask]) if you want to exclude those rows

person user3483203    schedule 28.09.2018