【问题标题】:pandas read_json returns object instead of datetime64 on some datetime64 columnspandas read_json 在某些 datetime64 列上返回对象而不是 datetime64
【发布时间】:2020-08-11 04:34:03
【问题描述】:

我有一个想要序列化为 JSON 的 DataFrame,并能够在 DataFrame 中读回它。有 2 个 datetime64 列,但其中一个作为对象返回。我也丢失了时区信息,但我从How do I keep the timezone of my index when serializing/deserializing a Pandas DataFrame using JSON 看到,我不能这样做。

wxdata.info()
pd.read_json(wxdata.to_json(date_format='iso')).info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 9853 entries, 0 to 9852
Data columns (total 30 columns):
 #   Column                          Non-Null Count  Dtype                     
---  ------                          --------------  -----                     
 0   time_of_day                     9853 non-null   datetime64[ns, US/Eastern]
 1   temp1                           9853 non-null   float64                   
 2   wind_chill                      9853 non-null   float64                   
 3   heat_index                      9853 non-null   float64                   
 4   dew_point                       9853 non-null   float64                   
 5   degree_day                      9853 non-null   float64                   
 6   density_altitude                9853 non-null   float64                   
 7   wet_bulb_globe_temp             9853 non-null   float64                   
 8   adjusted_altitude               9853 non-null   float64                   
 9   SAE_correction_factor           9853 non-null   float64                   
 10  rel_humidity                    9853 non-null   int64                     
 11  inst_wind_speed                 9853 non-null   float64                   
 12  inst_wind_dir                   9853 non-null   float64                   
 13  two_min_rolling_avg_wind_speed  9853 non-null   float64                   
 14  two_min_rolling_avg_wind_dir    9853 non-null   float64                   
 15  ten_min_rolling_avg_wind_speed  9853 non-null   float64                   
 16  ten_min_rolling_avg_wind_dir    9853 non-null   float64                   
 17  sixty_min_winddir_atpeak        9853 non-null   int64                     
 18  sixty_min_peak_windspeed        9853 non-null   float64                   
 19  ten_min_winddir_atpeak          9853 non-null   int64                     
 20  ten_min_peak_windspeed          9853 non-null   float64                   
 21  ten_min_wind_gust_time          9853 non-null   datetime64[ns, US/Eastern]
 22  rain_today                      9853 non-null   int64                     
 23  rain_this_week                  9853 non-null   int64                     
 24  rain_this_month                 9853 non-null   int64                     
 25  rain_this_year                  9853 non-null   int64                     
 26  rain_rate                       9853 non-null   int64                     
 27  raw_barom_pressure              9853 non-null   float64                   
 28  barom_press                     9853 non-null   float64                   
 29  solar_radiation                 9853 non-null   int64                     
dtypes: datetime64[ns, US/Eastern](2), float64(19), int64(9)
memory usage: 2.3 MB
<class 'pandas.core.frame.DataFrame'>
Int64Index: 9853 entries, 0 to 9852
Data columns (total 30 columns):
 #   Column                          Non-Null Count  Dtype              
---  ------                          --------------  -----              
 0   time_of_day                     9853 non-null   object             
 1   temp1                           9853 non-null   float64            
 2   wind_chill                      9853 non-null   float64            
 3   heat_index                      9853 non-null   float64            
 4   dew_point                       9853 non-null   float64            
 5   degree_day                      9853 non-null   float64            
 6   density_altitude                9853 non-null   float64            
 7   wet_bulb_globe_temp             9853 non-null   float64            
 8   adjusted_altitude               9853 non-null   float64            
 9   SAE_correction_factor           9853 non-null   float64            
 10  rel_humidity                    9853 non-null   int64              
 11  inst_wind_speed                 9853 non-null   float64            
 12  inst_wind_dir                   9853 non-null   float64            
 13  two_min_rolling_avg_wind_speed  9853 non-null   float64            
 14  two_min_rolling_avg_wind_dir    9853 non-null   float64            
 15  ten_min_rolling_avg_wind_speed  9853 non-null   float64            
 16  ten_min_rolling_avg_wind_dir    9853 non-null   float64            
 17  sixty_min_winddir_atpeak        9853 non-null   int64              
 18  sixty_min_peak_windspeed        9853 non-null   float64            
 19  ten_min_winddir_atpeak          9853 non-null   int64              
 20  ten_min_peak_windspeed          9853 non-null   float64            
 21  ten_min_wind_gust_time          9853 non-null   datetime64[ns, UTC]
 22  rain_today                      9853 non-null   int64              
 23  rain_this_week                  9853 non-null   int64              
 24  rain_this_month                 9853 non-null   int64              
 25  rain_this_year                  9853 non-null   int64              
 26  rain_rate                       9853 non-null   int64              
 27  raw_barom_pressure              9853 non-null   float64            
 28  barom_press                     9853 non-null   float64            
 29  solar_radiation                 9853 non-null   int64              
dtypes: datetime64[ns, UTC](1), float64(19), int64(9), object(1)
memory usage: 2.3+ MB

如您所见,第一个 datetime64 列作为对象而不是 datetime64 返回。在没有 date_format='iso' 开关的情况下执行此操作,'time_of_day' 返回为 int64,而不是 datetime64。

感谢您的帮助。

【问题讨论】:

  • 我也想知道这是否可能是因为 'time_of_day' 是第一列,可以用作索引。

标签: pandas to-json


【解决方案1】:

就是这样。我将“time_of_day”列重命名为“timestamp”,现在两列都是 datetime64。

https://pandas.pydata.org/docs/user_guide/io.html#io-json-reader

注意

如果 convert_dates=True 并且数据和/或列标签显示为“类似日期”,则可以将大整数值转换为日期。确切的阈值取决于指定的 date_unit。 ‘date-like’ 表示列标签符合以下条件之一:

它以'_at'结尾

以“_time”结尾

它以“时间戳”开头

它是'修改'

现在是“日期”

【讨论】:

  • 现在的问题变成了:pd.read_json() 可以使用 dateutil.parser.isoparse() 来返回一个 datetime 对象,因为我使用了 pd.to_json(date_format='iso') ?
【解决方案2】:

您可以将errors='coerce' 参数提供给日期转换方法。不可转换的条目将作为 NaT(不是时间)返回。然后你可以看到有问题的项目。例如:

df['time_of_day'] = pd.to_datetime(df['time_of_day'], 
                                   errors='coerce',
                                   exact='True',
                                   format='%Y-%m-%d' # provide your format here
                                  )

【讨论】:

  • 我正在使用带有 parse_dates 的 read_csv 读取初始数据。这将如何运作?
  • 我用 read_csv w/o parse_dates 读入了数据,然后尝试了你的建议。我没有收到任何不良记录。
  • 我想我知道为什么其中一列被读取为 datetime64。来自docs 是因为该列以“_time”结尾
  • 好观察!默认行为并不总是我们所想的那样。
  • 我认为这仍然可能是 read_json() 中的一个错误。我的 json 没有大整数值(如纪元时间),而是一个 ISO 8601 格式的字符串。例如:"time_of_day":{"0":"2020-06-15T16:41:52.000Z","1":"2020-06-15T16:42:52.000Z"。一个明显的“类日期”列不应该依赖列名来解释为日期时间。
猜你喜欢
  • 2014-06-04
  • 2017-01-27
  • 1970-01-01
  • 2013-11-14
  • 1970-01-01
  • 2019-07-23
  • 2019-03-23
  • 2019-12-12
  • 2015-06-02
相关资源
最近更新 更多