Faire de la Pythonic façon.
L'utilisation généralisée des macros dans Stata témoigne d'une autre philosophie de programmation.
Contrairement à Python, qui est un orientée objet, langage de programmation,
Stata est ado
langue (pas mata
) nécessite des macros afin de fonctionner comme
quelque chose de plus qu'un simple langage de script.
Les Macros peuvent être utilisés presque partout dans Stata (même dans les définitions de macros) pour deux raisons:
- Remplacement de texte
- L'évaluation de l'Expression
À l'aide de macros, l'utilisateur peut simplifier leur code, qui à son tour, permettra de réduire la
le potentiel pour des erreurs et garder bien rangé. L'inconvénient est que l'utilisation de macros
rend la syntaxe de la langue fluide.
Pour répondre à votre question, Pyexpander
fournit une partie de ce type de fonctionnalité en Python, mais c'est pas vraiment une
substitut. Pour les différents cas d'utilisation, vous aurez besoin d'une approche différente pour imiter
macro d'extension. En contraste avec Stata, il n'y a pas d'uniforme façon de le faire partout.
Mon conseil est de vous familiariser avec Python conventions plutôt que de
en essayant de programmer les choses de la "Stata façon". Par exemple, il est utile de rappeler
que le local et le global macros dans Stata correspondent à des variables en Python (local
dans une fonction, mondial à l'extérieur), tandis que les variables dans Stata correspondent à
Pandas.Series
ou une colonne d'un Pandas.DataFrame
. De Même, Stata ado
les programmes correspondent à des fonctions en Python.
La solution fournie dans l' @g.d.d.c est la réponse peut être un bon outil vers la réalisation de
ce que quelqu'un voudrais. Cependant, des étapes supplémentaires sont requises ici si vous voulez
ré-utiliser votre code.
À l'aide de votre jouet exemple:
import pandas as pd
import numpy as np
import statsmodels.api as sm
df = pd.read_stata('http://www.stata-press.com/data/r14/auto.dta')
In [1]: df[['mpg', 'weight', 'price']].head()
Out[1]:
mpg weight price
0 22 2930 4099
1 17 3350 4749
2 22 2640 3799
3 20 3250 4816
4 15 4080 7827
Supposons que vous voulez ré-utilisation de l'extrait de code suivant, mais avec différents
variables:
In [2]: Y = df['mpg']
In [3]: df['cons'] = 1
In [4]: X = df[['weight', 'price', 'cons']]
In [5]: reg = sm.OLS(Y, X).fit()
In [6]: print(reg.summary())
OLS Regression Results
==============================================================================
Dep. Variable: mpg R-squared: 0.653
Model: OLS Adj. R-squared: 0.643
Method: Least Squares F-statistic: 66.85
Date: Prob (F-statistic): 4.73e-17
Time: Log-Likelihood: -195.22
No. Observations: 74 AIC: 396.4
Df Residuals: 71 BIC: 403.3
Df Model: 2
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
weight -0.0058 0.001 -9.421 0.000 -0.007 -0.005
price -9.351e-05 0.000 -0.575 0.567 -0.000 0.000
cons 19.7198 0.811 24.322 0.000 18.103 21.336
==============================================================================
Omnibus: 29.900 Durbin-Watson: 2.347
Prob(Omnibus): 0.000 Jarque-Bera (JB): 60.190
Skew: 1.422 Prob(JB): 8.51e-14
Kurtosis: 6.382 Cond. No. 1.50e+04
==============================================================================
Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 1.5e+04. This might indicate that there are
strong multicollinearity or other numerical problems.
Comment pourriez-vous le faire?
Tout d'abord, créez une fonction:
def reg2(depvar, indepvars, results, df):
Y = df[depvar]
df['cons'] = 1
X = df[indepvars]
reg = sm.OLS(Y, X).fit()
if results != 0:
print(reg.summary())
Toutefois, notez que, bien que la chaîne de l'interpolation peut 'étendre' chaînes, ici
cette approche ne fonctionnera pas, car la fonction cible pour regresson analyse
ne pas accepter un unifiée de la chaîne du genre 'weight, price, cons'
.
Au lieu de cela, vous devez définir une liste avec les variables explicatives:
predictors = ['weight', 'price', 'cons']
reg2('mpg', predictors, 0, df)
Vous pouvez également prendre ce concept au niveau suivant par la construction d'un décorateur:
def load_and_reg2(func):
def wrapper(*args, **kwargs):
print()
print("Loading the dataset...")
print()
df = pd.read_stata('http://www.stata-press.com/data/r14/auto.dta')
sumvars = df[['mpg', 'weight', 'price']].head()
print(sumvars)
print()
func(*args, **kwargs, df = df)
return func(*args, **kwargs, df = df)
print()
print("Doing any other stuff you like...")
print()
dfshape = df.shape
print('Shape:', dfshape)
return wrapper
Et l'utiliser dans vos reg2()
fonction de:
@load_and_reg2
def reg2(depvar, indepvars, results, df):
Y = df[depvar]
df['cons'] = 1
X = df[indepvars]
reg = sm.OLS(Y, X).fit()
if results != 0:
print(reg.summary())
return reg
L'exemple est peut-être très simpliste, mais démontre la puissance de Python:
In [7]: [predictors = ['weight', 'price', 'cons']
In [8]: reg2('mpg', predictors, 1)
Loading the dataset...
mpg weight price
0 22 2930 4099
1 17 3350 4749
2 22 2640 3799
3 20 3250 4816
4 15 4080 7827
OLS Regression Results
==============================================================================
Dep. Variable: mpg R-squared: 0.653
Model: OLS Adj. R-squared: 0.643
Method: Least Squares F-statistic: 66.85
Date: Prob (F-statistic): 4.73e-17
Time: Log-Likelihood: -195.22
No. Observations: 74 AIC: 396.4
Df Residuals: 71 BIC: 403.3
Df Model: 2
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
weight -0.0058 0.001 -9.421 0.000 -0.007 -0.005
price -9.351e-05 0.000 -0.575 0.567 -0.000 0.000
cons 39.4397 1.622 24.322 0.000 36.206 42.673
==============================================================================
Omnibus: 29.900 Durbin-Watson: 2.347
Prob(Omnibus): 0.000 Jarque-Bera (JB): 60.190
Skew: 1.422 Prob(JB): 8.51e-14
Kurtosis: 6.382 Cond. No. 3.00e+04
==============================================================================
Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 3e+04. This might indicate that there are
strong multicollinearity or other numerical problems.
Doing any other stuff you like...
Shape: (74, 13)
Comme vous pouvez le voir, le décorateur d'autres résumés des choses, mais à l'aide fixe de la syntaxe.
Dans le Python univers des dictionnaires et des classes jouent aussi un rôle important dans
la réutilisation de code/résultats. Par exemple, un dictionnaire peut agir comme l'équivalent de
Stata est return
de l'espace pour stocker plusieurs macros, des scalaires, etc.
Envisager le légèrement modifié la version de notre jouet décorateur load_and_reg2
, ce qui
enregistre désormais des objets individuels dans un dictionnaire, D
, et le renvoie:
def load_and_reg2(func):
def wrapper(*args, **kwargs):
D = {}
print()
print("Loading the dataset...")
print()
df = pd.read_stata('http://www.stata-press.com/data/r14/auto.dta')
sumvars = df[['mpg', 'weight', 'price']].head()
D['sumvars'] = sumvars
print(sumvars)
print()
D['reg2'] = func(*args, **kwargs, df)
print()
print("Doing any other stuff you like...")
print()
dfshape = df.shape
D['dfshape'] = dfshape
print('Shape:', dfshape)
return D
return wrapper
Ensuite, vous pouvez facilement le faire:
In [9]: foo = reg2('mpg', predictors, 1)
In [10]: foo.keys()
Out[10]: dict_keys(['sumvars', 'reg2', 'dfshape'])
In [11]: foo['sumvars']
Out[11]:
mpg weight price
0 22 2930 4099
1 17 3350 4749
2 22 2640 3799
3 20 3250 4816
4 15 4080 7827
Les Classes peuvent introduire davantage de flexibilité dans le coût
d'une complexité supplémentaire:
class loadreg2return(object):
def __init__(self, sumvars=None, reg2=None, dfshape=None):
self.sumvars = sumvars
self.reg2 = reg2
self.dfshape = dfshape
def load_and_reg2(func):
def wrapper(*args, **kwargs):
print("Loading the dataset...")
print()
df = pd.read_stata('http://www.stata-press.com/data/r14/auto.dta')
sumvars = df[['mpg', 'weight', 'price']].head()
print(sumvars)
print()
reg2 = func(*args, **kwargs, df = df)
print()
print("Doing any other stuff you like...")
print()
dfshape = df.shape
loadreg2return(dfshape = dfshape)
print('Shape:', dfshape)
return loadreg2return(sumvars = sumvars, reg2 = reg2, dfshape = dfshape )
return wrapper
Cette version de notre jouet décorateur retourne:
In [12]: foo.dfshape
Out[12]: (74, 13)
In [13]: foo.sumvars
Out[13]:
mpg weight price
0 22 2930 4099
1 17 3350 4749
2 22 2640 3799
3 20 3250 4816
4 15 4080 7827
In [14]: foo.reg2.params
Out[14]:
weight -0.005818
price -0.000094
cons 39.439656
dtype: float64