Разница между методами map, applymap и apply в Pandas

Можете ли вы рассказать мне, когда использовать эти методы векторизации с базовыми примерами?

Я вижу, что map является методом Series тогда как остальные - методы DataFrame. Однако я запутался в методах apply и applymap. Почему у нас есть два метода применения функции к DataFrame? Опять же, простые примеры, иллюстрирующие использование, были бы замечательными!

Ответ 1

Прямо от Wes McKinney Python для анализа данных book, pg. 132 (я настоятельно рекомендовал эту книгу):

Еще одна частая операция - применение функции на 1D массивах к каждому столбцу или строке. Метод применения DataFrames выполняет именно это:

In [116]: frame = DataFrame(np.random.randn(4, 3), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])

In [117]: frame
Out[117]: 
               b         d         e
Utah   -0.029638  1.081563  1.280300
Ohio    0.647747  0.831136 -1.549481
Texas   0.513416 -0.884417  0.195343
Oregon -0.485454 -0.477388 -0.309548

In [118]: f = lambda x: x.max() - x.min()

In [119]: frame.apply(f)
Out[119]: 
b    1.133201
d    1.965980
e    2.829781
dtype: float64

Многие из наиболее распространенных статистических данных массива (например, сумма и среднее) - это методы DataFrame,     поэтому использование приложения не требуется.

Также могут использоваться элементы Python, основанные на элементе. Предположим, вы хотели вычислить форматированную строку из каждого значения с плавающей запятой в фрейме. Вы можете сделать это с помощью applymap:

In [120]: format = lambda x: '%.2f' % x

In [121]: frame.applymap(format)
Out[121]: 
            b      d      e
Utah    -0.03   1.08   1.28
Ohio     0.65   0.83  -1.55
Texas    0.51  -0.88   0.20
Oregon  -0.49  -0.48  -0.31

Причиной для имени applymap является то, что Series имеет метод карты для применения элементарной функции:

In [122]: frame['e'].map(format)
Out[122]: 
Utah       1.28
Ohio      -1.55
Texas      0.20
Oregon    -0.31
Name: e, dtype: object

Подводя итоги, apply работает на основе строки/столбца DataFrame, applymap работает по элементам на DataFrame, а map работает по элементам в серии.

Ответ 2

В этих ответах есть замечательная информация, но я добавляю свои собственные, чтобы четко суммировать, какие методы работают с массивом по сравнению с элементарно. jeremiahbuddha в основном делал это, но не упоминал Series.apply. У меня нет комментариев для комментариев.

  • DataFrame.apply работает со всеми строками или столбцами за раз.

  • DataFrame.applymap, Series.apply и Series.map работают на одном элемент в момент времени.

Существует много перекрытий между возможностями Series.apply и Series.map, что означает, что каждый из них будет работать в большинстве случаев. У них есть некоторые незначительные различия, хотя некоторые из них обсуждались в ответе osa.

Ответ 3

Добавляя к другим ответам, в Series есть также карта и применяются.

Применить может сделать DataFrame из серии; однако карта просто поместит серию в каждую ячейку другой серии, что, вероятно, не то, что вы хотите.

In [40]: p=pd.Series([1,2,3])
In [41]: p
Out[31]:
0    1
1    2
2    3
dtype: int64

In [42]: p.apply(lambda x: pd.Series([x, x]))
Out[42]: 
   0  1
0  1  1
1  2  2
2  3  3

In [43]: p.map(lambda x: pd.Series([x, x]))
Out[43]: 
0    0    1
1    1
dtype: int64
1    0    2
1    2
dtype: int64
2    0    3
1    3
dtype: int64
dtype: object

Кроме того, если бы я имел функцию с побочными эффектами, такими как "подключиться к веб - серверу", я бы, вероятно, использовать apply только для наглядности.

series.apply(download_file_for_every_element) 

Map может использовать не только функцию, но и словарь или другую серию. Скажем, вы хотите манипулировать перестановками.

принимать

1 2 3 4 5
2 1 4 5 3

Квадрат этой перестановки

1 2 3 4 5
1 2 5 3 4

Вы можете вычислить его с помощью map. Не уверен, что 0.15.1 документировано, но оно работает в 0.15.1.

In [39]: p=pd.Series([1,0,3,4,2])

In [40]: p.map(p)
Out[40]: 
0    0
1    1
2    4
3    2
4    3
dtype: int64

Ответ 4

@jeremiahbuddha упомянул, что применяются работы над строками/столбцами, а applymap работает по элементам. Но, похоже, вы все еще можете использовать приложение для элементарного вычисления....

    frame.apply(np.sqrt)
    Out[102]: 
                   b         d         e
    Utah         NaN  1.435159       NaN
    Ohio    1.098164  0.510594  0.729748
    Texas        NaN  0.456436  0.697337
    Oregon  0.359079       NaN       NaN

    frame.applymap(np.sqrt)
    Out[103]: 
                   b         d         e
    Utah         NaN  1.435159       NaN
    Ohio    1.098164  0.510594  0.729748
    Texas        NaN  0.456436  0.697337
    Oregon  0.359079       NaN       NaN

Ответ 5

Просто хотел указать, так как я боролся с этим немного

def f(x):
    if x < 0:
        x = 0
    elif x > 100000:
        x = 100000
    return x

df.applymap(f)
df.describe()

это не изменяет сам файл данных, его необходимо переназначить

df = df.applymap(f)
df.describe()

Ответ 6

Вероятно, простое объяснение разницы между apply and applymap:

apply переносит весь столбец в качестве параметра, а затем присваивает результат этому столбцу

applymap берет отдельное значение ячейки в качестве параметра и возвращает результат этой ячейке.

NB Если apply возвращает одно значение, у вас будет это значение вместо столбца после назначения и в итоге будет иметь только строку вместо матрицы.

Ответ 7

Сравнивая map, applymap и ap ply: Контекст Matters

Первое существенное отличие: ОПРЕДЕЛЕНИЕ

  • map определена ТОЛЬКО в серии
  • applymap определяется ТОЛЬКО в DataFrames
  • apply определяется на ОБА

Второе важное отличие: входной аргумент

  • map принимает dict s, Series или вызываемый
  • applymap и apply принимают только вызываемые

Третье главное отличие: ПОВЕДЕНИЕ

  • map поэлементно для серии
  • applymap поэлементно для DataFrames
  • apply также работает поэлементно, но подходит для более сложных операций и агрегации. Поведение и возвращаемое значение зависят от функции.

Четвертое основное отличие (самое важное): случай использования

  • map предназначен для отображения значений из одного домена в другой, поэтому оптимизирован для производительности (например, df['A'].map({1:'a', 2:'b', 3:'c'}))
  • applymap подходит для поэлементных преобразований в нескольких строках/столбцах (например, df[['A', 'B', 'C']].applymap(str.strip))
  • apply предназначен для применения любой функции, которая не может быть векторизована (например, df['sentences'].apply(nltk.sent_tokenize))

подведение

enter image description here

Сноски

  1. map при передаче словаря /Series будет отображать элементы на основе ключей в этом словаре /Series. Недостающие значения будут записаны как NaN на выходе.
  2. applymap в более поздних версиях был оптимизирован для некоторых операций. Вы найдете applymap немного быстрее, чем apply в некоторых случаях. Мое предложение состоит в том, чтобы проверить их обоих и использовать то, что работает лучше.

  3. map оптимизирована для поэлементного отображения и преобразования. Операции, в которых используются словари или серии, позволят пандам использовать более быстрые пути к коду для повышения производительности.

  4. Series.apply возвращает скаляр для агрегирующих операций, в противном случае Series. Аналогично для DataFrame.apply. Обратите внимание, что apply также имеет быстрые пути при вызове с некоторыми функциями NumPy, такими как mean, sum и т.д.

Ответ 8

Мое понимание:

С точки зрения функции:

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

например: lambda x: x.max()-x.mean().

Если функция должна применяться к каждому элементу:

1> Если/строка столбца находится, используйте apply

2> Если применяется ко всему кадру данных, используйте applymap

majority = lambda x : x > 17
df2['legal_drinker'] = df2['age'].apply(majority)

def times10(x):
  if type(x) is int:
    x *= 10 
  return x
df2.applymap(times10)

Ответ 9

сильный текст. Серии.map(arg, na_action = None)

Значения карты серии с использованием входного соответствия (a dict, Series или function).

Series.apply

Для применения более сложных функций на Серии.

DataFrame.apply

Примените функцию row-/по столбцу.

DataFrame.applymap

Примените функцию elementwise по всему DataFrame.

источник: карта в пандах

Ответ 10

СЧ:

В следующем примере показаны apply и applymap примененные к DataFrame.

Функция map - это то, что вы применяете только в серии. Вы не можете применить map на DataFrame.

applymap помнить, что apply может делать все, что может applymap, но apply имеет опции eXtra.

Опции X-фактора: axis и result_type где result_type работает только тогда, когда axis=1 (для столбцов).

df = DataFrame(1, columns=list('abc'),
                  index=list('1234'))
print(df)

f = lambda x: np.log(x)
print(df.applymap(f)) # apply to the whole dataframe
print(np.log(df)) # applied to the whole dataframe
print(df.applymap(np.sum)) # reducing can be applied for rows only

# apply can take different options (vs. applymap cannot)
print(df.apply(f)) # same as applymap
print(df.apply(sum, axis=1))  # reducing example
print(df.apply(np.log, axis=1)) # cannot reduce
print(df.apply(lambda x: [1, 2, 3], axis=1, result_type='expand')) # expand result

Как Замечание, серии map функции, не следует путать с Python map функции.

Первый применяется к Серии, чтобы отобразить значения, а второй - к каждому элементу итерируемого.


И, наконец, не следует путать dataframe apply метод с GroupBy apply метод.