使用Python ORM进行交叉制表(列联表)?

3

如果你在关系型数据库中对数据进行非常基础的统计探索,就必须计算交叉表格,也称为列联表(wikipedia page)。当你需要计算同时落入多个类别的项目数量时,这些是必不可少的。例如:有多少客户是女性且喜欢巧克力?

Scipy有一些方法可以对矩阵进行操作,使用histogram2d的变体。但是,为了进行有意义的统计分析,您需要能够拥有一个带有变量名称的表格,并从中指定要制表的变量。此外,它需要适用于其他类型的变量,而不仅仅是数字。实际上,数字制表是更复杂的,因为它需要进行分箱处理。R自然具有这样的函数,称为table,它可以很容易地移植到Python中。然而,请记住我在标题中提到我想使用ORM,为什么?因为交叉制表比生成它的数据要小得多,您可以从数据库中的数十亿条记录中计算出一个2x2的表格。我的观点是:在严肃的应用程序中,您无法负担将所有数据带入内存并循环遍历它的成本。因此,您必须将表设计转换为SQL查询,以便所有计数都由数据库引擎完成。ORM将处理必要的SQL方言调整,以便您可以在任何数据库后端上运行代码。一个简单交叉制表的MySQL SQL示例可以在here找到。

现在我想我已经让你对这个问题产生了动力,以下是问题:这个功能在任何Python ORM中实现了吗?如果使用SQLAlchemy或Django ORM,您将如何实现它?

1个回答

2

我不喜欢自己回答自己的问题,但有时我们只能等不及帮助。而且,我已经找到了一个好的答案,因此感到有责任与社区分享。所以,这里是答案:

table = self.session.query(Table.var1, Table.var2, func.count(Table)).group_by(Table.var1, Table.var2).all()

这将返回一个类似于(row,column,count)的元组列表。您可以从这个列表中组装您的列联表,并在需要时计算边际总数。值得一提的是,对于具有296110条记录的表格,var1和var2分别具有5个和90个级别,计算此表格花费了0.28秒
现在是一个用于组装和打印(2d)表格的小函数:
def pprint_table():
    colnames = list(set([i[1] for i in table]))
    rows = defaultdict(lambda:[0]*len(colnames))
    for r in table:
        rows[r[0]][colnames.index(r[1])] = r[2]
    print colnames, 'total'
    for rn, r in rows.items():
        print rn, r, sum(r)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接