用Python的方式来做。

Stata中宏的广泛使用反映了一种不同的编程理念。

与Python不同,Python是一种面向对象的通用编程语言,

Stata的ado语言(不是mata)需要宏才能作为

不仅仅是一种简单的脚本语言。在

宏几乎可以在Stata中的任何地方使用(甚至在宏定义中),有两个目的:文本替换

表达式求值

使用宏,用户可以简化他们的代码,这反过来又会减少

有可能出错并保持整洁。缺点是使用宏

呈现语言的语法流畅。在

要回答您的问题,Pyexpander

在Python中提供了一些此类功能,但实际上它不是

代替。对于不同的用例,您将需要不同的方法来模拟

宏观扩张。与Stata相比,没有一个统一的方法在任何地方进行。在

我的建议是熟悉Python的约定,而不是

试着用“Stata way”编程。例如,记住

Stata中的局部宏和全局宏对应于Python(local)中的变量

在函数中,全局外部),而Stata中的变量对应于

Pandas.Series或Pandas.DataFrame的列。类似地,Stata ado

程序对应于Python中的函数。在

@g.d.d.c的答案中提供的解决方案可能是实现目标的一个很好的工具

有人想要什么。但是,如果您愿意,这里需要额外的步骤

重复使用你的代码。在

以你的玩具为例: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

假设您希望重用以下代码片段,但是

变量:

^{pr2}$

你怎么可能那样做?在

首先,创建一个函数: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())

但是,请注意,虽然字符串插值可以“扩展”字符串,但这里

这种方法行不通,因为回归分析的目标函数

不接受'weight, price, cons'类型的统一字符串。在

相反,您需要用回归函数定义一个列表:predictors = ['weight', 'price', 'cons']

reg2('mpg', predictors, 0, df)

您还可以通过构造装饰器将这个概念提升到下一个层次: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

并在reg2()函数中使用:@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

这个例子可能非常简单,但它展示了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)

如您所见,decorator进一步抽象了一些东西,但是使用了固定的语法。在

在Python世界中,字典和类在

重复使用代码/结果。例如,字典可以相当于

Stata的return空间,用于存储多个宏、标量等

考虑一下我们的玩具装饰器load_and_reg2稍作修改的版本,它

现在将单个对象保存在字典D中并返回它: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

然后您可以轻松地执行以下操作: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

类可以以代价引入更多的灵活性

一些额外的复杂性: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

此版本的玩具装饰器返回: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

Logo

为开发者提供自动驾驶技术分享交流、实践成长、工具资源等,帮助开发者快速掌握自动驾驶技术。

更多推荐