【问题标题】:How to read MySQL timestamp(6) into pandas?如何将 MySQL 时间戳(6)读入 pandas?
【发布时间】:2015-09-04 22:11:50
【问题描述】:

我有一个 MySql 表,其时间戳具有微秒级分辨率:

+----------------------------+------+
| time                       | seq  | 
+----------------------------+------+
| 2015-06-19 02:17:57.389509 |    0 | 
| 2015-06-19 02:17:57.934171 |   10 |
+----------------------------+------+

我想将它读入熊猫数据框。使用

import pandas as pd
con = get_connection()
result = pd.read_sql("SELECT * FROM MyTable;", con=con)
print result

返回 NaT(不是时间):

    time  seq 
0   NaT    0  
1   NaT   10  

如何将其读入时间戳?

【问题讨论】:

  • 你能提供一些额外的信息吗? 1)你的熊猫版本是什么? 2) 什么是con?它是一个 sqlalchemy 引擎吗?还是有联系? (应该是 sqlalchemy 引擎) 3) 你能显示con.execute("SELECT * FROM MyTable;").fetchall()`` 的输出吗
  • @joris,“它应该是一个 sqlalchemy 引擎”不一定是真的。对于read_sql(),可以提供sqlite3 DBAPI2 对象,对吗?
  • 啊,是的,这是真的! (不是正式的,但确实有效),但仍然很有趣。然后您使用read_sql_table 提供的示例将不起作用。编辑:请注意,sqlite 是一个例外,为此官方支持 DBAPI 连接,也可用于写入帧,对于其他数据库类型,它仅适用于读取查询,不适用于读取或写入表。
  • 这里是docs 的链接,以防有人在寻找它。
  • @joris: 1) 熊猫版本 = 0.16.2。 --- 2) con 是与带有 MySQLdb 模块的数据库的连接:con = MySQLdb.connect(host='1.2.3.4', db='mydb') --- 3) con.execute 是不可能的,因为AttributeError: 'Connection' object has no attribute 'execute'

标签: python mysql pandas


【解决方案1】:

一般来说,要转换时间戳,可以使用pandas.to_datetime()

>>> import pandas as pd
>>> pd.to_datetime('2015-06-19 02:17:57.389509')
Timestamp('2015-06-19 02:17:57.389509')

docs,当从 SQL 读入时,可以显式强制将列解析为日期:

pd.read_sql_table('data', engine, parse_dates=['Date'])

或更明确地,指定格式字符串或参数字典以传递给pandas.to_datetime()

pd.read_sql_table('data', engine, parse_dates={'Date': '%Y-%m-%d'})

pd.read_sql_table('data', engine, parse_dates={'Date': {'format': '%Y-%m-%d %H:%M:%S'}})

添加快速概念验证。注意,我使用的是SQLITE。假设您将时间戳存储为字符串:

from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData
import pandas as pd

engine = create_engine('sqlite:///:memory:', echo=True)

datapoints = [{'ts': '2015-06-19 02:17:57.389509', 'seq': 0},
              {'ts':'2015-06-19 02:17:57.934171', 'seq': 10}]
metadata = MetaData()
mydata = Table('mydata', metadata,
    Column('ts', String),
    Column('seq', Integer),
)
metadata.create_all(engine)
ins = mydata.insert()
conn = engine.connect()
conn.execute(ins, datapoints)

foo = pd.read_sql_table('mydata', engine, parse_dates=['ts'])
print(foo)

输出:

                           ts  seq
0  2015-06-19 02:17:57.389509    0
1  2015-06-19 02:17:57.934171   10

或者,如果您将它们存储为日期时间对象,它的工作方式相同(代码差异是我将数据以日期时间格式存入数据库):

from datetime import datetime
from sqlalchemy import create_engine, Table, Column, Integer, DateTime, MetaData
import pandas as pd

engine = create_engine('sqlite:///:memory:', echo=True)

datapoints = [{'ts': datetime.strptime('2015-06-19 02:17:57.389509', '%Y-%m-%d %H:%M:%S.%f'), 'seq': 0},
              {'ts':datetime.strptime('2015-06-19 02:17:57.934171', '%Y-%m-%d %H:%M:%S.%f'), 'seq': 10}]
metadata = MetaData()
mydata = Table('mydata', metadata,
    Column('ts', DateTime),
    Column('seq', Integer),
)
metadata.create_all(engine)
ins = mydata.insert()
conn = engine.connect()
conn.execute(ins, datapoints)

foo = pd.read_sql_table('mydata', engine, parse_dates=['ts'])
print(foo)

输出相同:

                          ts  seq
0 2015-06-19 02:17:57.389509    0
1 2015-06-19 02:17:57.934171   10

希望这会有所帮助。

编辑为了尝试解决@joris的问题,sqlite确实将所有datetime对象存储为字符串,但是,内置适配器在获取时会自动将这些转换回datetime 对象。扩展第二个例子:

from sqlalchemy.sql import select
s = select([mydata])
res = conn.execute(s)
row = res.fetchone()
print(type(row['ts']))

结果为@​​987654337@

【讨论】:

  • 我试过你的例子,但它仍然导致NaT
  • 等我回到电脑前再看看。
  • @ThS,您的time 存储为什么类型?字符串还是日期时间?
  • 一些注意事项:我不知道与 SQLite 的比较是否有用,因为它没有 Datetime 类型(仅存储为字符串)。其次,在将它们存储为“日期时间”(但它只是列名)的第二种情况下,不需要显式的parse_dates
  • @joris - 实际上,从 SQLite 看来,我可以从两个版本中省略 parse_dates ......(刚刚测试过)。 mySQL 将如何存储时间戳?作为字符串?
猜你喜欢
  • 2016-08-22
  • 1970-01-01
  • 2012-09-11
  • 1970-01-01
  • 2014-08-26
  • 1970-01-01
  • 1970-01-01
  • 2018-03-30
  • 2020-01-13
相关资源
最近更新 更多