Разница между методами 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]()
Сноски
-
map
при передаче словаря /Series будет отображать элементы на основе ключей в этом словаре /Series. Недостающие значения будут записаны как NaN на выходе. -
applymap
в более поздних версиях был оптимизирован для некоторых операций. Вы найдете applymap
немного быстрее, чем apply
в некоторых случаях. Мое предложение состоит в том, чтобы проверить их обоих и использовать то, что работает лучше.
-
map
оптимизирована для поэлементного отображения и преобразования. Операции, в которых используются словари или серии, позволят пандам использовать более быстрые пути к коду для повышения производительности.
-
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
метод.