我目前有一个结构是一个字典:每个值都是一个包含数值的列表。这些数字列表中的每一个都包含您可以称为主键的东西(借用SQL惯用法),主键包含前三个值:年份、球员标识符和球队标识符。这是字典的关键。
因此,您可以通过传入年份、球员ID和球队ID的值来获得唯一的行,如下所示:
statline = stats[(2001, 'SEA', 'suzukic01')]
这会产生类似这样的结果
[305, 20, 444, 330, 45]
我想修改这个数据结构,使其可以通过这三个键中的任何一个快速求和:这样,您就可以通过传入年份、球员ID和球队ID中的一个,然后传递索引,轻松地对数字列表中给定索引的总数进行切片。我希望能够做一些像这样的事情
hr_total = stats[year=2001, idx=3]
其中idx 3对应于将被检索的数字列表中的第三列。
有什么想法吗?
发布于 2009-11-09 10:19:31
阅读有关数据仓库的知识。任何一本书。
请阅读星型架构设计。任何一本书。我是认真的。
你有几个维度:年份,球员,团队。
你有一个事实:得分
你想要一个这样的结构。
然后,您希望创建一组维度索引,如下所示。
years = collections.defaultdict( list )
players = collections.defaultdict( list )
teams = collections.defaultdict( list )
您的事实表可以是一个collections.namedtuple
。你可以使用类似这样的东西。
class ScoreFact( object ):
def __init__( self, year, player, team, score ):
self.year= year
self.player= player
self.team= team
self.score= score
years[self.year].append( self )
players[self.player].append( self )
teams[self.team].append( self )
现在,您可以查找给定尺寸值中的所有项目。这是一个附加到尺寸值的简单列表。
years['2001'] are all scores for the given year.
players['SEA'] are all scores for the given player.
等。您可以简单地使用sum()
将它们相加。多维查询是这样的。
[ x for x in players['SEA'] if x.year == '2001' ]
发布于 2009-11-09 10:02:23
将数据放入SQLite中,并使用它的关系引擎来完成这项工作。您可以创建内存中的数据库,甚至不必触摸磁盘。
发布于 2009-11-09 10:10:53
语法stats[year=2001, idx=3]
是无效的Python,您无法使其与那些方括号和“关键字参数”一起工作;您需要有一个函数或方法调用才能接受关键字参数。
所以,假设我们把它作为一个函数,像wells(stats, year=2001, idx=3)
一样被调用。我认为idx参数是强制的(这对于调用来说是非常特殊的,但您没有给出省略idx可能意味着什么的指示),并且year、playerid和teamid必须恰好存在一年。
使用您当前的数据结构,已经可以实现wells了:
def wells(stats, year=None, playerid=None, teamid=None, idx=None):
if idx is None: raise ValueError('idx must be specified')
specifiers = [(i, x) for x in enumerate((year, playerid, teamid)) if x is not None]
if len(specifiers) != 2:
raise ValueError('Exactly one of year, playerid, teamid, must be given')
ikey, keyv = specifiers[0]
return sum(v[idx] for k, v in stats.iteritems() if k[ikey]==keyv)
当然,这是stats
大小的O(N) --它必须检查其中的每个条目。请以这个简单的实现为基准来衡量正确性和性能。另一种解决方案(使用起来更快,但需要大量的准备时间)是将三个列表的字典(分别用于年份、播放I、团队)放在stats
的一侧,每个条目指示(或复制,但我认为通过全密钥指示)与该ikey / keyv对匹配的统计信息的所有条目。但目前还不清楚这种实现是否为时过早,所以请先试试这个简单的想法!-)
https://stackoverflow.com/questions/1698734
复制相似问题