Différence entre les méthodes map, applymap et apply dans les Pandas
pouvez-vous me dire quand utiliser ces méthodes de vectorisation avec des exemples de base?
je vois que map
est une méthode Series
tandis que le reste sont des méthodes DataFrame
. Je me suis trompé sur les méthodes apply
et applymap
. Pourquoi avons-nous deux méthodes pour appliquer une fonction à une base de données? Encore une fois, des exemples simples qui illustrent l'usage serait génial!
8 réponses
Directement à partir de Wes McKinney Python pour l'Analyse des Données livre, pg. 132 (j'ai fortement recommandé ce livre):
une autre opération fréquente consiste à appliquer une fonction sur des tableaux 1D à chaque colonne ou rangée. La méthode apply de DataFrame fait exactement cela:
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
la plupart des statistiques les plus courantes des tableaux (comme sum et mean) sont des méthodes de DataFrame., donc à l'aide d'appliquer est n'est pas nécessaire.
Les fonctions Pythonpeuvent aussi être utilisées. Supposons que vous vouliez calculer une chaîne formatée à partir de chaque valeur flottante dans le cadre. Vous pouvez le faire avec 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
la raison pour le nom applymap est que la série a une méthode de carte pour appliquer une fonction par élément:
In [122]: frame['e'].map(format)
Out[122]:
Utah 1.28
Ohio -1.55
Texas 0.20
Oregon -0.31
Name: e, dtype: object
en résumé, apply
fonctionne sur un rang / la base de la colonne de la DataFrame, applymap
travaille element-wise sur la DataFrame, et map
travaille element-wise sur la série.
il y a de grandes informations dans ces réponses, mais j'Ajoute les miennes pour résumer clairement quelles méthodes fonctionnent selon un tableau plutôt que selon un élément. jeremiahbuddha a surtout fait cela, mais n'a pas mentionné les séries.appliquer. Je n'ai pas le représentant pour commenter.
-
DataFrame.apply
fonctionne sur des rangées ou des colonnes entières à la fois. -
DataFrame.applymap
,Series.apply
, et "151930920 fonctionnent sur un élément à la fois.
il y a beaucoup de chevauchement entre les capacités de Series.apply
et Series.map
, ce qui signifie que l'un ou l'autre fonctionnera dans la plupart des cas. Il y a toutefois de légères différences, dont certaines ont été discutées dans la réponse de l'osa.
en ajoutant aux autres réponses, dans un Series
il y a aussi carte et appliquer .
Appliquer peut faire un DataFrame d'une série ; cependant, map va juste mettre une série dans chaque cellule d'une autre série, ce qui n'est probablement pas ce que vous voulez.
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
aussi si j'avais une fonction avec des effets secondaires, comme "se connecter à un serveur web", j'utiliserais probablement apply
par souci de clarté.
series.apply(download_file_for_every_element)
Map
peut utiliser non seulement une fonction, mais aussi un dictionnaire ou une autre série. disons que vous voulez manipuler permutations .
Prendre
1 2 3 4 5
2 1 4 5 3
le carré de cette permutation est
1 2 3 4 5
1 2 5 3 4
vous pouvez le calculer en utilisant map
. Pas sûr si auto-application est documentée, mais elle fonctionne dans 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
@jeremiahbuddha a mentionné que appliquer des travaux sur la ligne / les colonnes, tandis que applymap fonctionne par élément. Mais il semble que vous pouvez toujours utiliser Appliquer pour le calcul par élément....
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
je voulais Simplement faire remarquer, comme j'ai eu du mal avec ce pour un peu
def f(x):
if x < 0:
x = 0
elif x > 100000:
x = 100000
return x
df.applymap(f)
df.describe()
cela ne modifie pas le dataframe lui-même, doit être réassigné
df = df.applymap(f)
df.describe()
explication probablement la plus simple la différence entre appliquer et applymap:
apply prend la colonne entière comme paramètre et puis attribue le résultat à cette colonne
applymap prend la valeur de la cellule séparée comme paramètre et attribue le résultat à cette cellule.
NB si apply retourne la valeur unique vous aurez cette valeur au lieu de la colonne après assigner et finalement aura juste une rangée au lieu de matrice.
ma compréhension:
du point de vue de la fonction:
si la fonction possède des variables qui doivent être comparées à l'intérieur d'une colonne/ Rangée, utilisez
apply
.
p.ex.: lambda x: x.max()-x.mean()
.
si la fonction doit être appliquée à chaque élément:
1 > si une colonne/Rangée est située, utilisez apply
2 > si applicable à la totalité de dataframe, utiliser 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)
texte fort de la Série.carte (arg, na_action=None)
les valeurs de la Carte de Série à l'aide de l'entrée de la correspondance (dict, de la Série ou de la fonction).
de la Série.appliquer
Pour l'application de fonctions plus complexes sur une Série.
DataFrame.appliquer
appliquer une fonction ligne / colonne.
DataFrame.applymap
appliquer une fonction elementwise sur une base de données complète.
source: carte en pandas