gpt4 book ai didi

python - 旋转 SQLite 表,像 SQL 一样应该是

转载 作者:太空狗 更新时间:2023-10-30 02:50:36 26 4
gpt4 key购买 nike

我有一些数据。 224,000 行,在 SQLite 数据库中。我想从中提取时间序列信息以提供数据可视化工具。本质上,数据库中的每一行都是一个事件,该事件具有(除其他外并不严格相关的)自纪元以来以秒为单位的时间日期组和负责它的名称。我想提取数据库中每个名称每周有多少个事件。

这很简单:

SELECT COUNT(*), 
name,
strf("%W:%Y", time, "unixepoch")
FROM events
GROUP BY strf("%W:%Y", time, "unixepoch"), name
ORDER BY time

我们得到大约六千行数据。

count          name        week:year  
23............ fudge.......23:2009
etc...

但我不希望每个星期的每个名字都占一行 - 我想要每个名字占一行,每周占一列,如下所示:

Name      23:2009       24:2009    25:2009  
fudge........23............6............19
fish.........1.............0............12
etc...

现在,监控过程已经运行了 69 周,唯一名称的计数为 502。很明显,我对涉及对所有列(更不用说对行)进行硬编码的任何解决方案都不感兴趣。我不太热衷于任何涉及迭代很多的事情,比如 python 的 executemany(),但如果有必要我愿意接受它。 SQL 应该是集明智的,该死的。

最佳答案

在这种情况下,一个好的方法是不要将 SQL 推到令人费解且难以理解和维护的地步。让 SQL 做它方便的事情,并在 Python 中对查询结果进行后处理。

这是我编写的简单交叉表生成器的精简版。完整版提供行/列/总计。

您会注意到它具有内置的“分组依据”——最初的用例是使用 Python 和 xlrd 汇总从 Excel 文件中获得的数据。

您提供的 row_keycol_key 不必像示例中那样是字符串;它们可以是元组——例如(year, week) 在你的情况下——或者它们可以是整数——例如你有一个字符串列名到整数排序键的映射。

import sys

class CrossTab(object):

def __init__(
self,
missing=0, # what to return for an empty cell. Alternatives: '', 0.0, None, 'NULL'
):
self.missing = missing
self.col_key_set = set()
self.cell_dict = {}
self.headings_OK = False

def add_item(self, row_key, col_key, value):
self.col_key_set.add(col_key)
try:
self.cell_dict[row_key][col_key] += value
except KeyError:
try:
self.cell_dict[row_key][col_key] = value
except KeyError:
self.cell_dict[row_key] = {col_key: value}

def _process_headings(self):
if self.headings_OK:
return
self.row_headings = list(sorted(self.cell_dict.iterkeys()))
self.col_headings = list(sorted(self.col_key_set))
self.headings_OK = True

def get_col_headings(self):
self._process_headings()
return self.col_headings

def generate_row_info(self):
self._process_headings()
for row_key in self.row_headings:
row_dict = self.cell_dict[row_key]
row_vals = [row_dict.get(col_key, self.missing) for col_key in self.col_headings]
yield row_key, row_vals

def dump(self, f=None, header=None, footer='', ):
if f is None:
f = sys.stdout
alist = self.__dict__.items()
alist.sort()
if header is not None:
print >> f, header
for attr, value in alist:
print >> f, "%s: %r" % (attr, value)
if footer is not None:
print >> f, footer

if __name__ == "__main__":

data = [
['Rob', 'Morn', 240],
['Rob', 'Aft', 300],
['Joe', 'Morn', 70],
['Joe', 'Aft', 80],
['Jill', 'Morn', 100],
['Jill', 'Aft', 150],
['Rob', 'Aft', 40],
['Rob', 'aft', 5],
['Dozy', 'Aft', 1],
# Dozy doesn't show up till lunch-time
['Nemo', 'never', -1],
]
NAME, TIME, AMOUNT = range(3)
xlate_time = {'morn': "AM", "aft": "PM"}

print
ctab = CrossTab(missing=None, )
# ctab.dump(header='=== after init ===')
for s in data:
ctab.add_item(
row_key=s[NAME],
col_key= xlate_time.get(s[TIME].lower(), "XXXX"),
value=s[AMOUNT])
# ctab.dump(header='=== after add_item ===')
print ctab.get_col_headings()
# ctab.dump(header='=== after get_col_headings ===')
for x in ctab.generate_row_info():
print x

输出:

['AM', 'PM', 'XXXX']
('Dozy', [None, 1, None])
('Jill', [100, 150, None])
('Joe', [70, 80, None])
('Nemo', [None, None, -1])
('Rob', [240, 345, None])

关于python - 旋转 SQLite 表,像 SQL 一样应该是,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1835391/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com