防止Pandas to_json()将时间组件添加到日期对象

时间:2018-01-21 17:21:27

标签: python python-2.7 pandas date

我的数据框包含一些日期对象。我需要转换为json以便在JavaScript中使用,这需要YYYY-MM-DD,但to_json()会不断添加时间组件。我已经看到了许多首先转换为字符串的答案,但这是大约15个查询的循环的一部分,每个查询都有很多列(简化了SO问题)并且我不想将每个列转换硬编码为有很多。

import pandas as pd
from datetime import date
df = pd.DataFrame(data=[[date(year=2018, month=1, day=1)]])    
print df.to_json(orient='records', date_format='iso', date_unit='s')

输出:

[{"0":"2018-01-01T00:00:00Z"}]

期望的输出:

[{"0":"2018-01-01"}]

5 个答案:

答案 0 :(得分:3)

Pandas目前没有该功能。有一个公开的问题,如果在将来的版本中添加date_format参数的更多选项(这似乎是一个合理的功能请求),您应该订阅该问题:

<强> No way with to_json to write only date out of datetime #16492

在转出json之前手动将相关列转换为字符串可能是最佳选择。

答案 1 :(得分:2)

您可以使用strftime('%Y-%m-%d')格式:

df = pd.DataFrame(data=[[date(year=2018, month=1, day=1).strftime('%Y-%m-
    %d')]]

print(df.to_json(orient='records', date_format='iso', date_unit='s'))

# [{"0":"2018-01-01"}]

我认为这是目前最好的方法,直到pandas添加了一种只写日期时间之外的方法。

答案 2 :(得分:0)

演示:

来源DF:

In [249]: df = pd.DataFrame({
     ...:   'val':np.random.rand(5),
     ...:   'date1':pd.date_range('2018-01-01',periods=5),
     ...:   'date2':pd.date_range('2017-12-15',periods=5)
     ...: })

In [250]: df
Out[250]:
       date1      date2       val
0 2018-01-01 2017-12-15  0.539349
1 2018-01-02 2017-12-16  0.308532
2 2018-01-03 2017-12-17  0.788588
3 2018-01-04 2017-12-18  0.526541
4 2018-01-05 2017-12-19  0.887299

In [251]: df.dtypes
Out[251]:
date1    datetime64[ns]
date2    datetime64[ns]
val             float64
dtype: object

您可以在一个命令中将datetime列转换为字符串:

In [252]: df.update(df.loc[:, df.dtypes.astype(str).str.contains('date')].astype(str))

In [253]: df.dtypes
Out[253]:
date1     object
date2     object
val      float64
dtype: object

In [254]: df.to_json(orient='records')
Out[254]: '[{"date1":"2018-01-01","date2":"2017-12-15","val":0.5393488718},{"date1":"2018-01-02","date2":"2017-12-16","val":0.3085324043},{"
date1":"2018-01-03","date2":"2017-12-17","val":0.7885879674},{"date1":"2018-01-04","date2":"2017-12-18","val":0.5265407505},{"date1":"2018-0
1-05","date2":"2017-12-19","val":0.887298853}]'

或者,您可以将日期列转换为SQL端的字符串

答案 3 :(得分:0)

我也遇到了这个问题,但是由于我只查找日期,放弃了时区,因此我可以使用以下表达式解决该问题:

df = pd.read_json('test.json')
df['date_hour'] = [datetime.strptime(date[0:10],'%Y-%m-%d').date()for date in df['data_hora']]

因此,如果您在json文件=“ 2018-01-01T00:00:00Z”中具有df [date_hour]的'iso'date_format,则可以使用此解决方案。

这样,您可以提取真正重要的部分。重要的是必须使用列表理解来完成此操作,因为只能按字符串(或逐行)进行转换,否则,仅datetime.strptime会引发错误,指出不能与series一起使用。

答案 4 :(得分:0)

通用解决方案如下:

df.assign( **df.select_dtypes(['datetime']).astype(str).to_dict('list') ).to_json(orient="records")

它根据 dtype 选择日期时间列并将它们设置为 str 对象,以便在序列化期间保留日期格式。