Удалить низкочастотные значения из pandas.dataframe
Как я могу удалить значения из столбца в pandas.DataFrame
, что происходит редко, т.е. с низкой частотой? Пример:
In [4]: df[col_1].value_counts()
Out[4]: 0 189096
1 110500
2 77218
3 61372
...
2065 1
2067 1
1569 1
dtype: int64
Итак, мой вопрос: как удалить такие значения, как 2065, 2067, 1569
и другие? И как я могу сделать это для всех столбцов, которые содержат .value_counts()
как это?
ОБНОВЛЕНИЕ: О "низком" я имею в виду такие значения, как 2065
, Это значение встречается в col_1
1 (один) раз, и я хочу удалить такие значения, как это.
3 ответа
Я вижу, что есть два способа сделать это.
Для всего DataFrame
Этот метод удаляет значения, которые встречаются нечасто во всем DataFrame. Мы можем сделать это без циклов, используя встроенные функции, чтобы ускорить процесс.
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(0, high=9, size=(100,2)),
columns = ['A', 'B'])
threshold = 10 # Anything that occurs less than this will be removed.
value_counts = df.stack().value_counts() # Entire DataFrame
to_remove = value_counts[value_counts <= threshold].index
df.replace(to_remove, np.nan, inplace=True)
Колонка-на-колонки
Этот метод удаляет записи, которые встречаются нечасто в каждом столбце.
import pandas as np
import numpy as np
df = pd.DataFrame(np.random.randint(0, high=9, size=(100,2)),
columns = ['A', 'B'])
threshold = 10 # Anything that occurs less than this will be removed.
for col in df.columns:
value_counts = df[col].value_counts() # Specific column
to_remove = value_counts[value_counts <= threshold].index
df[col].replace(to_remove, np.nan, inplace=True)
Вы, вероятно, не хотите удалять всю строку в вашем DataFrame, если только один столбец имеет значения ниже вашего порога, поэтому я просто удалил эти точки данных и заменил их на None
,
Я перебираю каждый столбец и выполняю value_counts
на каждой. Затем я получаю значения индекса для каждого элемента, который находится на уровне или ниже целевого порогового значения. Наконец, я использую .loc
чтобы найти значения этих элементов в столбце, а затем заменить их None
,
df = pd.DataFrame({'A': ['a', 'b', 'b', 'c', 'c'],
'B': ['a', 'a', 'b', 'c', 'c'],
'C': ['a', 'a', 'b', 'b', 'c']})
>>> df
A B C
0 a a a
1 b a a
2 b b b
3 c c b
4 c c c
threshold = 1 # Remove items less than or equal to threshold
for col in df:
vc = df[col].value_counts()
vals_to_remove = vc[vc <= threshold].index.values
df[col].loc[df[col].isin(vals_to_remove)] = None
>>> df
A B C
0 None a a
1 b a a
2 b None b
3 c c b
4 c c None
Сapply
это можно сделать одной строкой.value_counts
возвращает количество уникальных значений. Вхождения сопоставляются с каждым значением с помощьюmap
.where
заменяет все значения, где условие не выполняется ( здесь : количество вхождений больше 1) на NaN .
In [6]: df = pd.DataFrame({'A': ['a', 'b', 'b', 'c', 'c'], 'B': ['a', 'a', 'b', 'c', 'c'], 'C': ['a', 'a', 'b', 'b', 'c']})
In [7]: df
Out[7]:
A B C
0 a a a
1 b a a
2 b b b
3 c c b
4 c c c
In [8]: df.apply(lambda col: col.where(col.map(col.value_counts()) > 1))
Out[8]:
A B C
0 NaN a a
1 b a a
2 b NaN b
3 c c b
4 c c NaN
Кредиты @Alexander за набор данных.