You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

保存Pandas DataFrame至Parquet文件时遇ValueError问题求助

问题

将Pandas DataFrame保存为Parquet文件时遇到报错,使用的代码如下:

import pandas as pd
import yfinance as yf

start_date = "2022-08-06"
end_date = "2024-08-05"

ticker = 'RELIANCE.NS'
data = yf.download(tickers=ticker, start=start_date, end=end_date, interval="1h")

data.reset_index(inplace=True)

data['Date'] = data['Datetime'].dt.date
data['Time'] = data['Datetime'].dt.time

data.to_parquet('./RELIANCE.parquet')

运行后报错:

ValueError: Can't infer object conversion type: 0

详细错误堆栈信息:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[1], line 15
     12 data['Date'] = data['Datetime'].dt.date
     13 data['Time'] = data['Datetime'].dt.time
---> 15 data.to_parquet('./RELIANCE.parquet')

File ~/python_venv/lib/python3.10/site-packages/pandas/util/_decorators.py:333, in deprecate_nonkeyword_arguments.<locals>.decorate.<locals>.wrapper(*args, **kwargs)
    327 if len(args) > num_allow_args:
    328     warnings.warn(
    329         msg.format(arguments=_format_argument_list(allow_args)),
    330         FutureWarning,
    331         stacklevel=find_stack_level(),
    332     )
--> 333 return func(*args, **kwargs)

File ~/python_venv/lib/python3.10/site-packages/pandas/core/frame.py:3113, in DataFrame.to_parquet(self, path, engine, compression, index, partition_cols, storage_options, **kwargs)
   3032 """
   3033 Write a DataFrame to the binary parquet format.
   3034 
   (...)
   3109 >>> content = f.read()
   3110 """
   3111 from pandas.io.parquet import to_parquet
-> 3113 return to_parquet(
   3114     self,
   3115     path,
   3116     engine,
   3117     compression=compression,
   3118     index=index,
   3119     partition_cols=partition_cols,
   3120     storage_options=storage_options,
   3121     **kwargs,
   3122 )

File ~/python_venv/lib/python3.10/site-packages/pandas/io/parquet.py:480, in to_parquet(df, path, engine, compression, index, storage_options, partition_cols, filesystem, **kwargs)
    476 impl = get_engine(engine)
    478 path_or_buf: FilePath | WriteBuffer[bytes] = io.BytesIO() if path is None else path
--> 480 impl.write(
    481     df,
    482     path_or_buf,
    483     compression=compression,
    484     index=index,
    485     partition_cols=partition_cols,
    486     storage_options=storage_options,
    487     filesystem=filesystem,
    488     **kwargs,
    489 )
    491 if path is None:
    492     assert isinstance(path_or_buf, io.BytesIO)

File ~/python_venv/lib/python3.10/site-packages/pandas/io/parquet.py:349, in FastParquetImpl.write(self, df, path, compression, index, partition_cols, storage_options, filesystem, **kwargs)
    344     raise ValueError(
    345         "storage_options passed with file object or non-fsspec file path"
    346     )
    348 with catch_warnings(record=True):
--> 349     self.api.write(
    350         path,
    351         df,
    352         compression=compression,
    353         write_index=index,
    354         partition_on=partition_cols,
    355         **kwargs,
    356     )

File ~/python_venv/lib/python3.10/site-packages/fastparquet/writer.py:1304, in write(filename, data, row_group_offsets, compression, file_scheme, open_with, mkdirs, has_nulls, write_index, partition_on, fixed_text, append, object_encoding, times, custom_metadata, stats)
   1301 check_column_names(data.columns, partition_on, fixed_text,
   1302                    object_encoding, has_nulls)
   1303 ignore = partition_on if file_scheme != 'simple' else []
-> 1304 fmd = make_metadata(data, has_nulls=has_nulls, ignore_columns=ignore,
   1305                     fixed_text=fixed_text,
   1306                     object_encoding=object_encoding,
   1307                     times=times, index_cols=index_cols,
   1308                     partition_cols=partition_on, cols_dtype=cols_dtype)
   1309 if custom_metadata:
   1310     kvm = fmd.key_value_metadata or []

File ~/python_venv/lib/python3.10/site-packages/fastparquet/writer.py:904, in make_metadata(data, has_nulls, ignore_columns, fixed_text, object_encoding, times, index_cols, partition_cols, cols_dtype)
    902     se.name = column
    903 else:
--> 904     se, type = find_type(data[column], fixed_text=fixed,
    905                          object_encoding=oencoding, times=times,
    906                          is_index=is_index)
    907 col_has_nulls = has_nulls
    908 if has_nulls is None:

File ~/python_venv/lib/python3.10/site-packages/fastparquet/writer.py:122, in find_type(data, fixed_text, object_encoding, times, is_index)
    120 elif dtype == "O":
    121     if object_encoding == 'infer':
--> 122         object_encoding = infer_object_encoding(data)
    124     if object_encoding == 'utf8':
    125         type, converted_type, width = (parquet_thrift.Type.BYTE_ARRAY,
    126                                        parquet_thrift.ConvertedType.UTF8,
    127                                        None)

File ~/python_venv/lib/python3.10/site-packages/fastparquet/writer.py:357, in infer_object_encoding(data)
    355     s += 1
    356 else:
--> 357     raise ValueError("Can't infer object conversion type: %s" % data)
    358 if s > 10:
    359     break

ValueError: Can't infer object conversion type: 0       2022-08-08
1       2022-08-08
2       2022-08-08
3       2022-08-08
4       2022-08-08
           ...    
3398    2024-08-02
3399    2024-08-02
3400    2024-08-02
3401    2024-08-02
3402    2024-08-02
Name: Date, Length: 3403, dtype: object
解决方案

报错原因是生成的Date和Time列是Python原生的date和time对象类型,这类不属于Parquet标准支持的数据类型,fastparquet引擎无法自动推断转换格式,因此抛出错误。以下是三种修复方式:

方式一:将Date和Time列转为字符串类型

把原生date/time对象转换为字符串,Parquet可以完美处理字符串类型:

import pandas as pd
import yfinance as yf

start_date = "2022-08-06"
end_date = "2024-08-05"

ticker = 'RELIANCE.NS'
data = yf.download(tickers=ticker, start=start_date, end=end_date, interval="1h")

data.reset_index(inplace=True)

# 转换为字符串格式
data['Date'] = data['Datetime'].dt.date.astype(str)
data['Time'] = data['Datetime'].dt.time.astype(str)

data.to_parquet('./RELIANCE.parquet')

方式二:保留原Datetime列,不拆分日期时间

如果不需要单独的Date和Time列,直接保留原始的Datetime列即可——它是pandas的datetime64类型,Parquet完全支持:

import pandas as pd
import yfinance as yf

start_date = "2022-08-06"
end_date = "2024-08-05"

ticker = 'RELIANCE.NS'
data = yf.download(tickers=ticker, start=start_date, end=end_date, interval="1h")

data.reset_index(inplace=True)

# 移除拆分Date和Time的代码
data.to_parquet('./RELIANCE.parquet')

方式三:切换到pyarrow引擎

如果必须保留原生date/time对象,可以切换到pyarrow引擎,它对Python原生日期时间类型的支持更友好:

import pandas as pd
import yfinance as yf

start_date = "2022-08-06"
end_date = "2024-08-05"

ticker = 'RELIANCE.NS'
data = yf.download(tickers=ticker, start=start_date, end=end_date, interval="1h")

data.reset_index(inplace=True)

data['Date'] = data['Datetime'].dt.date
data['Time'] = data['Datetime'].dt.time

# 指定使用pyarrow引擎
data.to_parquet('./RELIANCE.parquet', engine='pyarrow')

注意:若未安装pyarrow,需先执行pip install pyarrow完成安装。

内容的提问来源于stack exchange,提问作者pkj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 03:29:54