Фильтрация чисел в Pandas: как получать только числовые данные

Раздел: Основы Python -> Pandas

Фильтрация чисел в Pandas: основные подходы

Как отфильтровать строки DataFrame, оставив только те, которые можно интерпретировать как числа?

Наиболее универсальный способ - использовать функцию pd.to_numeric с параметром errors='coerce'. Она пытается преобразовать каждый элемент в число, а при неудаче заменяет его на NaN. Затем можно отфильтровать строки, где результат не равен NaN, с помощью .notna().

import pandas as pd

df = pd.DataFrame({'data': ['123', 'abc', '45.6', '7e2', '']})
mask = pd.to_numeric(df['data'], errors='coerce').notna()
filtered = df[mask]
print(filtered)

обработка больших данных python (обработка больших данных в python)

   data
0   123
2  45.6
3   7e2

очистка данных python (очистка данных в python)

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

Как выбрать только числовые столбцы в DataFrame?

Метод DataFrame.select_dtypes(include=['number']) возвращает подмножество столбцов, которые имеют числовой тип (int, float, complex). Это полезно для анализа больших таблиц, где нужно работать исключительно с числами.

df = pd.DataFrame({'A': [1, 2], 'B': ['x', 'y'], 'C': [3.0, 4.0]})
numeric_cols = df.select_dtypes(include='number')
print(numeric_cols)

Python подготовка данных (подготовка данных в python)

   A    C
0  1  3.0
1  2  4.0

работа с dataframe python (работа с dataframe в python)

Обратите внимание: столбцы с типом object, даже если они содержат числа, не попадут в выборку.

Как проверить, является ли значение числом, без Pandas?

Если данные находятся в обычном списке, можно использовать встроенную функцию isinstance() или метод строк str.isdigit() (только для целых положительных). Для более точной проверки применяют регулярные выражения.

import re

data = ['123', '-45.6', 'abc', '1e2', '']
def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

numbers = [x for x in data if is_number(x)]
print(numbers)

Python работа с большими данными (работа с большими данными в python)

['123', '-45.6', '1e2']

структурированные данные python (структурированные данные в python)

Вариант с try/except надёжен, но может быть медленным на больших наборах.

Как отфильтровать числа, записанные с разделителями тысяч или в разных форматах?

Используйте pd.to_numeric с параметром errors='coerce' после предварительной очистки строк (удаление пробелов, замена запятых).

series = pd.Series(['1,234', '5.678', '12,345.67', 'abc'])
cleaned = series.str.replace(',', '')
numeric = pd.to_numeric(cleaned, errors='coerce').notna()
print(series[numeric])

генерация данных python (генерация данных в python)

0       1,234
1       5.678
2    12,345.67
dtype: object

После фильтрации потребуется конвертировать строки в числовой тип.

Типичные ошибки и их решения

  • Ошибка: pd.to_numeric возвращает NaN для значений, которые выглядят как числа, но имеют лишние символы (пробелы, знаки валют). Решение: предварительно очистить строки с помощью str.strip() и str.replace().
  • Ошибка: Метод str.isdigit() не распознаёт отрицательные числа или числа с плавающей точкой. Решение: использовать pd.to_numeric или регулярное выражение r'^-?\d+(\.\d+)?([eE][+-]?\d+)?$'.
  • Ошибка: При фильтрации строк по маске .notna() теряются индексы. Решение: сохранять исходный индекс с помощью reset_index(drop=True) при необходимости.
  • Ошибка: Столбец содержит смесь типов (int и str). Решение: перед проверкой преобразовать весь столбец в строковый тип через astype(str).
- обработка данных на python (обработка данных на python)
- обработка символьных данных python (обработка символьных данных в python)
- Python преобразование в строку (преобразование в строку в python)

Расширенные примеры фильтрации чисел

Пример 1: Фильтрация с помощью регулярных выражений

Пример
import pandas as pd
import re

df = pd.DataFrame({'raw': ['$1,200.50', '25%', '3.14', 'some text', '-0.001']})
pattern = r'^-?\$?\d{1,3}(,\d{3})*(\.\d+)?%?$'
def is_numeric_advanced(s):
    return bool(re.match(pattern, s))

mask = df['raw'].apply(is_numeric_advanced)
print(df[mask])
         raw
0  $1,200.50
1        25%
2       3.14
4    -0.001

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

Пример 2: Отбор числовых колонок по dtype и конвертация

Пример
df = pd.DataFrame({
    'id': [1, 2],
    'value': [10.5, 20.3],
    'category': ['A', 'B'],
    'code': ['101', '202']
})
# Выбрать числовые колонки
numeric_df = df.select_dtypes(include=['int64', 'float64'])
print(numeric_df.dtypes)

# Принудительная конвертация строкового столбца 'code' в числа
numeric_df['code'] = pd.to_numeric(df['code'], errors='coerce')
print(numeric_df)
id        int64
value    float64
dtype: object
   id  value  code
0   1   10.5   101
1   2   20.3   202

Обратите внимание: столбец 'category' не попал в выборку. Добавление 'code' произошло после конвертации – важно следить за типом исходных данных.

Пример 3: Фильтрация с учётом NaN и None

Пример
import numpy as np
df = pd.DataFrame({'col': [1, 'two', np.nan, None, '3.0', 'NaN']})
# Способ 1: pd.to_numeric
mask1 = pd.to_numeric(df['col'], errors='coerce').notna()
print('Способ 1:', df[mask1])

# Способ 2: проверка на число + исключение NaN
def is_num(x):
    try:
        float(x)
        return True
    except (ValueError, TypeError):
        return False

mask2 = df['col'].apply(is_num)
print('Способ 2:', df[mask2])
Способ 1:   col
0    1
3  NaN  # !!! NaN интерпретирован как число
Способ 2:   col
0    1
4  3.0

Первый способ считает NaN числом (так как float('nan') не вызывает ошибки). Второй способ через float(x) также допускает NaN, но при использовании np.nan в строке возникает TypeError – поэтому None отсекается. Для исключения NaN нужно добавить проверку not np.isnan(x).

Пример 4: Использование np.isnan для чистки результата

Пример
series = pd.Series([1, 2, np.nan, 4, None, '5'])
numeric = pd.to_numeric(series, errors='coerce')
mask = numeric.notna() & ~np.isnan(numeric)
# Или короче: mask = numeric.apply(lambda x: not np.isnan(x))
print('Числа без NaN:', series[mask])
Числа без NaN: 0    1
1    2
3    4
5    5
dtype: object

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

Пример 5: Многоуровневая фильтрация (числа + положительные)

Пример
df = pd.DataFrame({'val': ['-5', '0', '3.14', 'abc', '100']})
numeric_mask = pd.to_numeric(df['val'], errors='coerce').notna()
positive_mask = pd.to_numeric(df['val'], errors='coerce') >= 0
filtered = df[numeric_mask & positive_mask]
print(filtered)
   val
1   0
2  3.14
4  100

Объединение масок позволяет гибко настраивать условия отбора.

фильтрация чисел в Python - comments

En
выводить только числа python (python)