En regardant les noyaux de Kaggle, qui introduit le code de participant de Kaggle, j'ai vu un code R qui fait un usage intensif de do.call ()
. Puisque do.call ()
était presque nouveau pour moi, je l'ai recherché et j'ai trouvé que c'était une fonction relativement classique et qu'elle n'était pas difficile à utiliser. Notez ci-dessous pour ne pas l'oublier.
Tout d'abord, je citerai le manuel CRAN.
do.call - Execute a Function Call
Description
do.call constructs and executes a function call from a name or a function and a list of arguments to be passed to it.
Usage
do.call(what, args, quote = FALSE, envir = parent.frame())
Arguments
- what either a function or a non-empty character string naming the function to be called.
- args a list of arguments to the function call. The names attribute of args gives the argument names.
- quote a logical value indicating whether to quote the arguments.
- envir an environment within which to evaluate the call. This will be most useful if what is a character string and the arguments are symbols or quoted expressions.
La fonction est "Appel de fonction". Le langage R a un riche ensemble de fonctions Apply, il semble donc qu'il soit célèbre, mais il semble que ce do.call () soit également utilisé selon le cas. Il semble prendre quatre arguments comme décrit ci-dessus, mais les deux premiers, l'objet fonction "what" et l'argument "args" qui lui sont passés, sont obligatoires. "args" doit être une variable de liste.
Voici quelques exemples d'utilisation.
Tout d'abord, définissez la fonction.
# define my own function
myrange <- function (larg) {
nv <- unlist(larg)
rg <- max(nv) - min(nv)
return(rg)
}
Ici, nous utilisons «iris» auquel R.
# Data.Frame example
head(iris)
Table 1. Iris Dataset
Do.call () la fonction définie "myrange".
do.call(myrange, list(iris$Sepal.Length))
# Out: 3.6
Comme prévu, la valeur maximale de «Sepal.Lengh» - la valeur minimale (3,6) a été affichée. Pour le moment, lorsqu'il est calculé avec la plage intégrée R (), il était de 4,3, 7,9 (valeur minimale, valeur maximale), donc la solution est cohérente avec 3,6 (= 7,9 --4,3) ci-dessus.
Vérifions un autre exemple. Tout d'abord, préparez une fonction pour normaliser la valeur numérique. Préparez un exemple de données d'entrée et exécutez do.call () comme suit.
normalize <- function(x, m=mean(x), s=sd(x)) {
(x - m) /s
}
myseq = list(c(1, 3, 6, 10, 15))
do.call(normalize, myseq)
# -1.0690449676497 -0.712696645099798 -0.17817416127495 0.534522483824849 1.4253932901996
La moyenne et l'écart type de la liste numérique de sortie sont
mean of normalized =
[1] -5.572799e-18
standard deviation =
[1] 1
Puisqu'il s'agit d'une valeur proche de 0 et 1 comme indiqué dans, on peut voir que la normalisation attendue peut être exécutée.
Il semble que do.call () de R soit similaire à la fonction intégrée de Python map (), mais je ne l'utilise pas beaucoup personnellement, donc cette fois je vais le comparer avec apply () de Pandas. (Référence: "Python for Data Analysis" --O'reilly media) Commencez par préparer des exemples de données.
# Sample Data
frame = pd.DataFrame(np.random.randn(4,3), columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])
frame
** Table 2. Data Example**
Préparez une fonction pour calculer la plage (valeur maximale-valeur minimale) et appliquez-la () à pd.DataFrame.
# define lambda function
f = lambda x: x.max() - x.min()
frame[['d']].apply(f)
# if I execute frame['d'].apply(f), error is raised. "apply()" is for pd.DataFrame
C'est le comportement attendu.
Out: d 4.016529
dtype: float64
Pour spécifier des colonnes numériquement, utilisez iloc [] dans le modèle suivant.
frame.iloc[:, [2]].apply(f)
# Out: e 2.160329
# dtype: float64
Notez que puisque nous voulons que la séquence soit une fonction donnée, nous devons spécifier des colonnes dans une liste, comme frame [['d']]
ou frame.iloc [:, [2]]
. Est. (Si ce paramètre est défini sur frame ['d']
, frame.iloc [:, 2]
, il sera interprété comme apply () pour l'objet pd.Series et le traitement pour chaque élément scalaire, ce qui entraînera une erreur.)
Avec cela, la même opération que R et do.call () a été réalisée.
Bien que do.call () soit une fonction rarement vue (uniquement pour moi?), Elle semble être utilisée dans la situation de "combinaison après traitement de data.frame". Cependant, les fonctions Apply sont plus pratiques et do.call () semble être écrit de manière "classique". Personnellement, je ne veux pas utiliser do.call () positivement, mais quand je vois do.call () dans le code humain, je veux le comprendre correctement sans me précipiter.
Je ne trouve rien qui correspond à do.call () en Python, mais il semble que l'opération souhaitée puisse être réalisée en effectuant un traitement à l'aide de la notation apply () ou d'inclusion de liste de Pandas (avec les données séparées).
(R a utilisé la version 3.3.1 (sur le notebook jupyter), Python a utilisé la version 3.5.2 (sur le notebook jupyter).)
Recommended Posts