将时间戳+数据从mysql导入到python并绘制时间序列

时间:2013-08-06 00:12:24

标签: python mysql mysql-python

我有一个我想访问的mysql表并从中提取数据。该表的结构如下所示:

| Id | datestamp |时间戳| bloodSugar |碳水化合物|胰岛素|

| 1 | 2013-08-05 | 18:28:17 | 6.7 | 76 | 6.6 |

NB:使用CURTIME()生成时间戳条目 NB2:请原谅可怕的桌子 - 我会发布一张图片,但还没有足够的代表点这样做:(

我正在尝试提取时间戳和bloodSugar值,以便绘制时间序列:x轴上的时间(HH:MM)和y轴上的bloodSugar值。但是我遇到了一些问题...

问题:在python中将数据提取到列表中时,时间戳显示为datetime.timedelta(0,58753)个条目。我希望这些在HH:MM中,以便我可以根据它们绘制数据。

问题:有没有办法简单地将timedelta格式化为HH:MM格式?如果这是不可能的,那么请告诉我如何解决这个问题(例如,使用mysqldb的另一个获取技术,或用其他东西替换CURTIME()等。)。

免责声明:我是一个菜鸟,希望学习,所以请尽可能通过解释提供。谢谢!

代码:

import MySQLdb as mdb
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import dates
import datetime

con = mdb.connect('localhost', 'testuser', 'test623', 'test');
with con:
    cur = con.cursor()
    #importing data into a list for analysis
    cur.execute("SELECT * FROM Diabetes")

    rows = cur.fetchall()

    data = []
    for row in rows:
        data.append(row)

    A = data

    d = [a[1] for a in A]
    t = [a[2] for a in A]
    b = [a[3] for a in A]
    c = [a[4] for a in A]
    novo = [a[5] for a in A] 

    #here is my attempt at trying to reformat the time-entries... But doesn't work..
    formatted_time = []    
    for delta_time in t:
        hours, remainder = divmod(delta_time[1], 3600)  
        minutes, seconds = divmod(remainder, 60)   

        duration_formatted = '%s:%s:%s' % (hours, minutes, seconds)
        formatted_time.append(duration_formatted)
print formatted_time


fig, ax = plt.subplots()
ax.plot_date(t, b)
fig.autofmt_xdate()
plt.show()

1 个答案:

答案 0 :(得分:0)

您有一堆时间戳存储为两个不相交的列,称为datestamp和timestamp。您没有告诉我们这些列的数据类型。 (请记住,TIMESTAMP是一个MySQL保留字,因此对于列名称来说是一个相当糟糕的选择。)

此类数据的最佳做法是将日期和时间合并到DATETIME类型的单个列中。你可以把它称为obstime(观察时间)或某些这样的事情。您可以使用NOW()函数填充此字段。

如果此信息与多个医疗机构有关,您可能需要处理时区。但这是另一组问题。

您可以重写MySQL查询,将日期戳和时间戳列合并到一个DATETIME列中。尝试此操作从表中检索DATETIME

  SELECT id, bloodsugar, carbohydrates, insuline,
         CAST(CONCAT(`datestamp`, ' ', `timestamp`) AS DATETIME) obstime
    FROM Diabetes
   ORDER BY id

我不确定你的问题是什么hh:mm你想要的信息。从第一次测量开始,您想要hh:mm的经过时间吗?如果您正在绘制这些东西,也许您希望自第一次测量以来hh:mm:ss中的观测值。让我们解决这个问题吧。

此查询为您提供第一次测量 - 第一次测量。

    SELECT MIN(CAST(CONCAT(`datestamp`, ' ', `timestamp`) AS DATETIME)) firstobstime
      FROM Diabetes

您可以将该查询加入到您的其他人中。

   ...
  FROM Diabetes AS d
  JOIN (
    SELECT MIN(CAST(CONCAT(`datestamp`, ' ', `timestamp`) AS DATETIME)) firstobstime
      FROM Diabetes
  ) AS f

此连接不需要任何ON子句;连接的第二部分只产生一行。

所以,那么你可以从一开始就按分钟得到观察列表。

SELECT TIMEDIFF(CAST(CONCAT(d.`datestamp`, ' ', d.`timestamp`) AS DATETIME),
                d.firstobstime) AS obstimeoffset
         d.bloodsugar, d.carbohydrates, d.insuline
  FROM Diabetes AS d
  JOIN (
    SELECT MIN(CAST(CONCAT(`datestamp`, ' ', `timestamp`) AS DATETIME)) firstobstime
      FROM Diabetes
       ) AS f        
 ORDER BY obstimeoffset

我认为这就是你想要的。

专业提示:在程序中的查询中避免使用SELECT *。当您向表中添加列时,它会使您的程序中断。

另一个专业提示:在DATETIME列中合并日期和时间。

第三个专业提示:我没有在你的桌子上看到任何patient_id或experiment_id或任何此类事情。正如您设计的那样,它适用于一名患者和一系列观察。您可能希望使其更加通用。这比为每位患者或实验添加另一张表更好。