通过Python为选定的MySQL表创建图表/统计数据

3 投票
2 回答
2914 浏览
提问于 2025-04-15 19:15

我想先听听你们的意见,关于我该如何处理这个任务,而不仅仅是如何写代码。

我现在想做的是:我有很多数据存储在一个mysql表里,这些数据包含了很多独特的名字和日期(也就是说,日期是一个单独的字段)。我的目标是能够选择一个特定的名字(用rawinput,未来可能会加一个下拉菜单),然后查看这个名字的每月趋势,包含移动平均值,可能还有其他一些统计数据,比如收入、每月收入、点击量等等。你们有什么建议?是通过python把这些数据转到excel工作簿里,还是有办法在python中直接展示这些信息(当然,图表要能和excel比较)?

谢谢!

2 个回答

0

你的问题可以分成两个主要部分:分析数据和展示数据。我假设你已经知道怎么分析数据了,现在你在想怎么展示这些数据。

这个问题特别适合用网页应用来解决。你有没有什么理由想要避免使用网页应用呢?

如果你对网页编程和编程本身都很陌生,那么像web2py这样的工具可能是个简单的入门选择。这里有一个简单的教程

如果你想做一个以桌面数据库为主的应用,可以看看dabo。它让创建数据库表的视图变得非常简单。它是基于wxpython构建的,wxpython也有很多简单的图表功能。

2

分析这些数据(名字、日期)可以看作是发出临时的SQL查询,以获取时间序列信息。

你会根据数据集的大小,通过一个日期/时间范围来“抽样”你的信息(可以是按天、周、月、年,或者更详细到小时、分钟)。

我经常使用这样的查询,其中日期字段会根据抽样频率进行截断,在mysql中,DATE_FORMAT函数非常好用(postgres和oracle分别使用date_trunc和trunc)。

你想在数据中看到的内容会在你的WHERE条件中体现。

select DATE_FORMAT(date_field,'%Y-%m-%d') as day,
       COUNT(*) as nb_event
FROM yourtable
WHERE name = 'specific_value_to_analyze'
GROUP BY DATE_FORMAT(date_field,'%Y-%m-%d');

执行这个查询并将结果输出到一个csv文件。你可以直接使用mysql命令来实现,但我推荐写一个python脚本来执行这个查询,这样你可以使用getopt选项来格式化输出(可以选择是否包含列标题,使用不同于默认的分隔符等等)。你甚至可以根据一些选项动态构建查询。

要绘制这些信息,可以看看时间序列工具。如果你有缺失的数据(某些日期在SQL查询结果中不会出现),你需要谨慎选择工具。我认为Excel不太适合这个(或者我不够熟练),但可以作为一个起点。

个人来说,我觉得dygraph这个javascript库在时间序列绘图方面非常不错,它可以使用csv文件作为数据源。在这种配置中要小心,由于跨域安全限制,csv文件和显示Dygraph对象的html页面应该在同一个服务器上(或者根据你的浏览器的安全限制来决定)。

我习惯使用django来构建这样的web应用,因为这是我最喜欢的web框架,我会把url调用封装成这样:

GET /timeserie/view/<category>/<value_to_plot>
GET /timeserie/csv/<category>/<value_to_plot> 

第一个url调用一个视图,简单地输出一个模板文件,里面有一个变量引用了获取csv文件的url,用于Dygraph对象:

<script type="text/javascript">
  g3 = new Dygraph(
    document.getElementById("graphdiv3"),
    "{{ csv_url }}",
    {
      rollPeriod: 15,
      showRoller: true
    }
  );
</script>

第二个url调用一个视图,生成sql查询并将结果以text/csv格式输出,以便Dygraph渲染。

这个“自制”的方案可以简单也可以扩展,能够轻松在任何台式电脑上运行,还可以扩展为输出json格式,以供其他javascript库/框架使用。

另外,还有一些开源工具与这样的报告相关(但时间序列功能往往不够满足我的需求),比如Pentaho、JasperReport、SOFA。你可以在这些工具中将查询作为数据源放入报告中,并构建输出时间序列的图表。

我发现如今的web技术结合合适的javascript库/框架,真的开始能够挑战那些老旧的经典BI工具的报告方式,并让事情变得更互动了 :-)

撰写回答