【问题标题】:Save date column with NAT(null) from pandas to parquet将带有 NAT(null) 的日期列从熊猫保存到镶木地板
【发布时间】:2020-11-03 04:06:28
【问题描述】:

我需要将整数格式可为空的日期值 ('YYYYMMDD') 读取到 pandas,然后将此 pandas 数据帧以 Date32[Day] 格式保存到 Parquet,以便 Athena Glue Crawler 分类器将该列识别为日期。下面的代码不允许我将列保存到 pandas 的镶木地板:

import pandas as pd

dates = [None, "20200710", "20200711", "20200712"]
data_df = pd.DataFrame(dates, columns=['date'])
data_df['date'] = pd.to_datetime(data_df['date']).dt.date
data_df.to_parquet(r'my_path', engine='pyarrow')

我在下面收到此错误:

Traceback (most recent call last):
  File "", line 123, in convert_column
    result = pa.array(col, type=type_, from_pandas=True, safe=safe)
  File "pyarrow\array.pxi", line 265, in pyarrow.lib.array
  File "pyarrow\array.pxi", line 80, in pyarrow.lib._ndarray_to_array
TypeError: an integer is required (got type datetime.date)

如果我将 None 值移到日期列表的末尾,这将毫无问题地工作,并且 pyarrow 会将日期列推断为 Date32[Day]。我的猜测是,由于 dt.date 的 Pandas 列类型是 object 加上该列的第一个值是 NaT (不是时间),pyarrow 无法从 Pandas 数据框中推断该列为 Date32[Day] 或一些样本值,它会将该列推断为Integer。什么是将此数据框列保存为镶木地板作为Date32[Day] 列而不对列值进行排序的好方法?谢谢。

【问题讨论】:

    标签: python-3.x pandas parquet amazon-athena pyarrow


    【解决方案1】:

    你是对的。由于第一个值是 NaT,您需要在不更改数据类型的情况下将其删除。我使用了下面的代码。

    import pandas as pd
    
    dates = [None, "20200710", "20200711", "20200712"]
    data_df = pd.DataFrame(dates, columns=['date'])
    data_df['date'] = pd.to_datetime(data_df['date']).dt.date
    
    # In addition, add this line to remove NaT without changing type
    # Change strfttime as you want (I have used YMD)
    data_df['date'] = [d.strftime('%Y-%m-%d') if not pd.isnull(d) else '' for d in data_df['date']]
    
    data_df.to_parquet(r'my_path', engine='pyarrow')
    

    我希望这对您有用并且错误已解决。

    【讨论】:

    • 我昨天花了一些时间,现在使用以下代码。 data_df['date'] = data_df['date'].replace({pd.NaT: None})
    • 也感谢您解决此问题。
    【解决方案2】:

    这是 pyarrow 1.0 (https://issues.apache.org/jira/browse/ARROW-842 / https://github.com/apache/arrow/pull/7537) 中修复的错误。上面的 sn-p 现在可以正常工作了:

    In [2]: dates = [None, "20200710", "20200711", "20200712"] 
       ...: data_df = pd.DataFrame(dates, columns=['date']) 
       ...: data_df['date'] = pd.to_datetime(data_df['date']).dt.date                                                                                                                                                  
    
    In [3]: data_df                                                                                                                                                                                                    
    Out[3]: 
             date
    0         NaT
    1  2020-07-10
    2  2020-07-11
    3  2020-07-12
    
    In [4]: data_df.to_parquet(r'my_path', engine='pyarrow')                                                                                                                                                           
    
    In [5]: import pyarrow.parquet as pq                                                                                                                                                                               
    
    In [6]: pq.read_table(r'my_path')                                                                                                                                                                                  
    Out[6]: 
    pyarrow.Table
    date: date32[day]
    

    【讨论】:

      猜你喜欢
      • 2017-04-25
      • 1970-01-01
      • 2020-03-11
      • 2018-12-01
      • 1970-01-01
      • 2022-11-24
      • 2019-10-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多