首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >pandas.read_sql和解释日期指定为周

pandas.read_sql和解释日期指定为周
EN

Stack Overflow用户
提问于 2014-08-23 11:50:53
回答 1查看 3.2K关注 0票数 1

我有一个这种格式的SQL表,我想阅读它并将其转换成熊猫时态。

代码语言:javascript
运行
复制
y (year)  w (week)   d (some data)
2009      1          10
2009      2          15
...

做这件事的好方法是什么?

我知道read_sql()的parse_dates参数,或者使用DatetimeIndex手动设置索引。我无法理解如何使用周数据来实现这一点。我尝试了以下方法。谢谢。

代码语言:javascript
运行
复制
# gives NaT for year & week:
df = pd.read_sql("SELECT y, w, d FROM t",
                 db, parse_dates={"y":"%Y", "w":"%U"})

# gives wrong dates for yw - e.g. all 2009-01-01:
df = pd.read_sql("SELECT CONCAT(y,'/',w) as yw, d FROM t",
                 db, parse_dates={"yw": "%Y/%U"})

# throws DateParseError exception:
df = pd.read_sql("SELECT CONCAT(y,'W',w) as yw, d FROM t",
                 db)
df.index = pd.DatetimeIndex(df.yw)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-23 14:04:07

实际上,我认为最优雅的方法是在SQL中执行转换:

代码语言:javascript
运行
复制
sql = "SELECT DATE_ADD(MAKEDATE(y, 1), INTERVAL w WEEK) as date, d FROM test.t"
df = pd.read_sql(sql, engine)
print(df)

收益率

代码语言:javascript
运行
复制
         date   d
0  2009-01-08  10
1  2009-01-15  15

要在Python中实现等效的操作,需要更多的锅炉板,因为AFAIK Pandas不提供任何将年份和周号转换为日期的开箱即用的设施。当然,您可以使用循环和datetime模块逐个将数字转换为datetime.datetime对象。

一种更快的方法是使用NumPy的datetime64和timedelta64 dtype作为NumPy数组执行日期算术:

代码语言:javascript
运行
复制
sql = "SELECT y, w, d FROM t"
df = pd.read_sql(sql, engine)

date = (df['y'].astype('<i8')-1970).view('<M8[Y]')
delta = (df['w'].astype('<i8')*7).view('<m8[D]')
df['date'] = date+delta
df = df[['date', 'd']]
print(df)

收益率

代码语言:javascript
运行
复制
        date   d
0 2009-01-08  10
1 2009-01-15  15

编辑:根据注释中哈迪的回答,还可以使用MySQL的日期函数计算SQL中的日期

代码语言:javascript
运行
复制
sql = "SELECT STR_TO_DATE(CONCAT(y,':',w,':1'), '%x:%v:%w') as date, d FROM test.t"    
df = pd.read_sql(sql, engine)

产额

代码语言:javascript
运行
复制
         date   d
0  2008-12-29  10
1  2009-01-05  15

注意,根据MySQL文档%v,意味着

代码语言:javascript
运行
复制
Week (01..53), where Monday is the first day of the week; WEEK() mode 3; used with %x

后来的在同一页上,模式3意味着

代码语言:javascript
运行
复制
Mode    First day of week   Range   Week 1 is the first week …
3       Monday              1-53    with 4 or more days this year

对于意味着“今年有4天或更多天”的模式值,根据ISO 8601:1988来编号。

因此,如果您希望周数与ISO8601:1988保持一致,那么对于STR_TO_DATE,您应该使用%v (或%u),而不是%V (或%U)。

请注意,我上面的第一个答案并不将该周解释为ISO 8601周数;它仅计算每周从1月1日起的7天。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25461627

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档