Удалите низкочастотные значения из 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 (один) раз, и я хочу удалить такие значения.

Ответ 1

Я вижу, что вы можете сделать это двумя способами.

Для всего 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)

Ответ 2

Вероятно, вы не хотите удалять всю строку в вашем 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