Сообщить об ошибке.

Поиск и замена значений в Series/DataFrame в pandas

Синтаксис:

df = DataFrame.replace(to_replace=None, value=None, *, inplace=False, 
                       limit=None, regex=False, method=no_default)

s = Series.replace(to_replace=None, value=None, *, inplace=False, 
                   limit=None, regex=False, method=no_default)

Параметры:

  • to_replace=None - принимаемые типы: str, regex, list, dict, Series, int, float или None.

    Как найти значения, которые будут заменены:

    • если передается str, regex или число:

      • numeric: числовые значения, равные to_replace будут заменены значением аргумента value
      • str: строка, точно совпадающая с to_replace, будет заменена значением аргумента value
      • regex: регулярные выражения, соответствующие to_replace будут заменены значением аргумента value

    • если передается список значений: str, regex или число:

      • Во-первых, если to_replace и value являются списками, то они должны иметь одинаковую длину.
      • Во-вторых, если regex=True, то все строки в обоих списках будут интерпретироваться как регулярные выражения, в противном случае они будут совпадать напрямую. Это не имеет большого значения для аргумента value, так как существует только несколько возможных регулярных выражений подстановки, которые можно использовать.
      • правила замены строк, регулярных выражений и чисел применяются, как указано выше (как если бы передавалась str, regex или число).

    • если передается словарь dict:

      • Для Series, словарь указывает различные значения замены для разных существующих значений данных. Например, {'a': 'b', 'y': 'z'} заменяет значение 'a' на 'b' и 'y' на 'z'. Чтобы использовать словарь dict таким образом, то аргумент value НЕ указывается.
      • Для DataFrame, ключ словаря указывает на индексную метку столбца. Например, словарь {'a': 1, 'b': 'z'} ищет значение 1 в столбце 'a' и значение 'z' в столбце 'b' и заменяет эти значения тем, что указано в value. В этом случае аргумент value не должен иметь значение None. Это можно рассматривать как частный случай передачи двух списков, за исключением того, что вы указываете столбец для поиска.
      • Для DataFrame вложенные словари, например, {'a': {'b': np.nan}}, читаются следующим образом: найдите в столбце 'a' значение 'b' и замените его на NaN, при этом необязательный аргумент value НЕ указывается. Также можно вкладывать регулярные выражения. Обратите внимание, что имена столбцов (ключи словаря верхнего уровня во вложенном словаре) не могут быть регулярными выражениями.
    • если передаются None, то это означает, что аргумент regex должен быть строкой, скомпилированным регулярным выражением или (list, dict, numpy.ndarray или Series) таких элементов. Если value также равно None, то это должен быть вложенный словарь {'a': {'b': np.nan}} или Series.

  • value=None - принимает: скалярное значение, dict, list, str, regex и None (по умолчанию). Используется для замены значений, соответствующих to_replace. Для DataFrame можно использовать словарь значений, который указывает, какое значение использовать для каждого столбца (столбцы, отсутствующие в словаре, заполнены не будут). Регулярные выражения, строки и списки или словари таких объектов также разрешены.

  • inplace=False - если True, операция выполняется на месте и возвращается None.

  • limit=None - Сколько совершать замен (целое число). Устарел, начиная с версии 2.1.0.

  • regex=False - принимает bool или те же типы, что и to_replace, по умолчанию False. Следует ли интерпретировать аргументы to_replace и/или value как регулярные выражения. Если True, то to_replace должно быть строкой. Кроме того, это может быть строка регулярного выражения или список, словарь или массив регулярных выражений, и в этом случае to_replace должно быть None.

  • method=no_default - метод, который следует использовать при замене, когда to_replace является скаляром, списком или кортежем, а аргумент value=None. Устарел, начиная с версии 2.1.0.

Возвращаемое значение:

Описание:

Методы DataFrame.replace() и Series.replace() модуля pandas динамически заменяет значения DataFrame/Series соответственно другими значениями, указанными в to_replace. Этот метод отличается от обновления значений с помощью свойств .loc или .iloc, которые требуют указания местоположения.

Примечания.

  • Подстановка регулярных выражений выполняется с помощью re.sub(). Правила замены те же, что и в re.sub().
  • Регулярные выражения будут подставляться только для строк, это означает, что нельзя предоставить, например, регулярное выражение, соответствующее числовым типам. Однако, если числа являются строками, то это делать можно.
  • Этот способ замены значений имеет массу вариантов. Рекомендуется экспериментировать и играть с этим методом, чтобы получить интуитивное представление о том, как он работает.
  • Когда используется словарь dict в качестве значения to_replace, то под капотом аргумент to_replace будет иметь значение key, а аргумент value будет принимать значение value из dict.

Возможные исключения:

  • AssertionError: Если регулярное выражение не является bool, а to_replace не равно None.

  • TypeError:

    • Если аргумент to_replace не является скалярным, списком, словарем dict или None
    • Если аргумент to_replace является dict, а аргумент value не является list, dict, nympy.ndarray или Series
    • Если аргумент to_replace=None, а аргумент regex НЕ компилируется в регулярное выражение или представляет собой list, dict, nympy.ndarray или Series.
    • При замене нескольких объектов bool или datetime64 и аргументы to_replace не совпадают с типом заменяемого значения/
  • ValueError: Если аргументам to_replace и value передаются список или nympy.ndarray, но они имеют разную длину.

Примеры использования DataFrame.replace()

Скалярные значения аргументов to_replace и value

>>> import pandas as pd
>>> s = pd.Series([1, 2, 3, 4, 5])
>>> s.replace(1, 5)
# 0    5
# 1    2
# 2    3
# 3    4
# 4    5
# dtype: int64
>>> df = pd.DataFrame({'A': [0, 1, 2, 3, 4],
...                    'B': [5, 6, 7, 8, 9],
...                    'C': ['a', 'b', 'c', 'd', 'e']})

>>> df.replace(0, 5)
#     A  B  C
# 0  5  5  a
# 1  1  6  b
# 2  2  7  c
# 3  3  8  d
# 4  4  9  e

Аргумент to_replace принимает список

>>> df.replace([0, 1, 2, 3], 4)
#     A  B  C
# 0  4  5  a
# 1  4  6  b
# 2  4  7  c
# 3  4  8  d
# 4  4  9  e
>>> df.replace([0, 1, 2, 3], [4, 3, 2, 1])
#     A  B  C
# 0  4  5  a
# 1  3  6  b
# 2  2  7  c
# 3  1  8  d
# 4  4  9  e
>>> s.replace([1, 2], method='bfill')
# 0    3
# 1    3
# 2    3
# 3    4
# 4    5
# dtype: int64

Аргумент to_replace принимает регулярное выражение

>>> df = pd.DataFrame({'A': ['bat', 'foo', 'bait'],
...                    'B': ['abc', 'bar', 'xyz']})

>>> df.replace(to_replace=r'^ba.$', value='new', regex=True)
#         A    B
# 0   new  abc
# 1   foo  new
# 2  bait  xyz
>>> df.replace({'A': r'^ba.$'}, {'A': 'new'}, regex=True)
#         A    B
# 0   new  abc
# 1   foo  bar
# 2  bait  xyz
>>> df.replace(regex=r'^ba.$', value='new')
#         A    B
# 0   new  abc
# 1   foo  new
# 2  bait  xyz
>>> df.replace(regex={r'^ba.$': 'new', 'foo': 'xyz'})
#         A    B
# 0   new  abc
# 1   xyz  new
# 2  bait  xyz
>>> df.replace(regex=[r'^ba.$', 'foo'], value='new')
#         A    B
# 0   new  abc
# 1   new  new
# 2  bait  xyz

Чтобы понять особенности параметра to_replace, сравним поведение s.replace({'a': None}) и s.replace('a', None). Для этого создадим новую серию:

>>> s = pd.Series([10, 'a', 'a', 'b', 'a'])

Когда используется словарь dict в качестве значения аргумента to_replace, то это похоже на то, как если бы значения в dict были равны параметру value. Выражение s.replace({'a': None}) эквивалентно выражению s.replace(to_replace={'a': None}, value=None, method=None):

>>> s.replace({'a': None})
# 0      10
# 1    None
# 2    None
# 3       b
# 4    None
# dtype: object

Когда значение аргумента value не передано явно, а to_replace является скаляром, списком или кортежем, то метод использует аргумент method (по умолчанию 'pad') для выполнения замены. Вот почему, в примере ниже, значения 'a' заменяются на 10 в строках 1 и 2 и 'b' в строке 4.

Аргумент method и его поведение устарели.

>>> s.replace('a')
# 0    10
# 1    10
# 2    10
# 3     b
# 4     b
# dtype: object

С другой стороны, если None передается явно, то оно будет соблюдаться:

>>> s.replace('a', None)
# 0      10
# 1    None
# 2    None
# 3       b
# 4    None
# dtype: object