python - 有没有办法在 Python 中使用循环自动执行用户函数?
问题描述
我一直在尝试在 Python 中实现以下 SAS 代码,虽然我在将代码转换为我需要的表时没有遇到任何问题,但我一直在通过每次更改参数来手动执行该函数。
SAS 代码:
%LET SOURCEDATA =
PRACTICE.RURAL_SHOPS;
%MACRO DATAPROCESSOR(YEAR =, QUARTER =, COL1 =, COL2 =, KEYCOL =);
PROC SQL;
CREATE TABLE RURALSHOP&YEAR&QUARTER AS
SELECT
&KEYCOL,
SUM(SHOPNO) AS SHOPNO&YEAR&QUARTER,
SUM(OPSHOP) AS OPSHOP&YEAR&QUARTER,
SUM(CLSHOP) AS CLSHOP&YEAR&QUARTER
FROM
&SOURCEDATA
WHERE
&COL1 = &YEAR AND &COL2 = &QUARTER
GROUP BY
&KEYCOL;
QUIT;
%MEND DATAPROCESSOR;
%MACRO REPEAT;
%DO I = 2014% TO 2019;
%DO J = 1% TO 4;
%DATAPROCESSOR(YEAR = &I, QUARTER = &J, COL1 = YEAR, COL2 = QUARTER, KEYCOL = AREACODE);
%END;
%END;
%MEND;
%REPEAT;
有没有办法实现在 Python 中使用循环自动执行函数的部分?这是我目前在 Python 中得到的:
sample_data = pd.DataFrame({"YEAR" : [2014, 2014, 2015, 2015, 2016, 2016, 2017, 2017, 2018, 2018, 2019, 2019], \
"QUARTER" : [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4], \
"AREACODE" : [100001, 100001, 100002, 100002, 100003, 100003, 100004, 100004, 100005, 100005, 100006, 100006], \
"SHOPNO" : [10, 12, 31, 5, 6, 9, 1, 3, 4, 0, 10, 2], \
"OPSHOP" : [1, 1, 3, 6, 2, 1, 0, 1, 0, 0, 2, 1], \
"CLSHOP" : [0, 0, 5, 1, 2, 0, 2, 1, 3, 5, 6, 0]})
def createmaster(df, keycol, keycol1, keycol2, year, quarter):
df = df[(df["{}".format(keycol1)] == year) & (df["{}".format(keycol2)] == quarter)].groupby("{}".format(keycol)).sum()
df = df.rename(columns = {"SHOPNO" : "SHOPNO{}{}".format(year, quarter),
"OPSHOP" : "OPSHOPNO{}{}".format(year, quarter),
"CLSHOP" : "CLSHOP{}{}".format(year, quarter)})
df = df.drop(columns = ["YEAR", "QUARTER"])
return df
解决方案
在 SAS 中,您应该在此处执行的操作是PROC MEANS
使用一条CLASS
语句运行,该语句将生成您所要求的内容,而几乎不需要任何代码。
这是通过一次传递数据,然后两次传递汇总数据来完成的,没有什么复杂的:只是一个摘要,一个快速传递以修复输出名称,然后是一个转置。我在这里写 SAS 只是为了展示 Python 应该是怎样的。这使用sashelp.prdsale
了与您的结构相当相似的数据集。
proc means data=sashelp.prdsale nway;
class country region year quarter;
var actual predict;
output out=prd_means sum(actual)= sum(predict)=;
run;
data prd_names;
set prd_means;
name = catx('_','actual',year,quarter);
value = actual;
output;
name = catx('_','predict',year,quarter);
value = predict;
output;
keep name value country region;
run;
proc transpose data=prd_names out=prd_vars;
by country region;
var value;
id name;
run;
因此,在 Python 中,让我们以同样的方式进行 - 获取汇总摘要,然后根据需要重新调整它。我将使用saspy
抓取prdsale
数据集;您可以在示例数据集上使用此代码。
import pandas as pd
#Everything from here to ...
import saspy
sas = saspy.SASsession(cfgname='winiomIWA')
prdsale = sas.sasdata2dataframe(table='prdsale',libref='sashelp')
#...here is just getting the dataframe set up - use your own dataframe here.
sums = prdsale.groupby(['COUNTRY','REGION','YEAR','QUARTER']).agg ('sum').unstack(['YEAR','QUARTER'])
print(sums)
你真正需要的是最后一行(和导入)旁边的:.groupby([... var list to summarize by, inc. year and quarter at the end]).agg('sum').unstack(['YEAR','QUARTER'])
.
在这里,groupby
告诉它在计算总和时如何对数据进行分组,agg
说要对变量求和,然后unstack
说要为这两个变量重新整形(意思是将这些变量的行变成列)。
我也怀疑pivot_table()
会这样做......
pv = prdsale.pivot_table(index=['COUNTRY','REGION'],columns=['YEAR','QUARTER'],
values=['ACTUAL','PREDICT'],aggfunc='sum')
两者都返回基本相同的东西,我不知道如果这很重要的话,哪个更快。有关此示例的另一个示例,请参见此问题/答案(尽管那里实际上并没有任何聚合)。
推荐阅读
- python - 为什么我们不能将日期时间提供给线性回归以及 toordinal() 与任何其他整数数据类型有何不同?
- wordpress - Wordpress - 自定义分类重写 URL
- c# - c# Entity Framework Eager Loading - 不适合我
- angular - 当我用 ngfor 和 ngif 点击时,如何只显示项目的信息?(本机脚本/角度)
- javascript - 如何修复nodejs中未处理的承诺拒绝?
- excel - 如何使用此 vba 代码添加其他 mac 地址?
- marklogic - 如何在 MarkLogic 数据中心快速入门中映射对象和数组?
- deep-learning - 在具有 1 个对象的图像上训练对象检测模型,并使用具有多个对象的图像对其进行测试
- visual-studio-code - 在 Visual Studio Code 中查找并替换为换行符和回车符
- julia - 从 Julia 文档中训练 CNF 示例时出现错误消息