有没有办法从 pandas read_csv 中“提取”dtype 转换功能?

Posted

技术标签:

【中文标题】有没有办法从 pandas read_csv 中“提取”dtype 转换功能?【英文标题】:Is there any way to "extract" the dtype conversion functionality from pandas read_csv? 【发布时间】:2022-01-18 20:17:21 【问题描述】:

我有以下数据框,其中所有列都是对象类型。 我的目标是推断每列的真实类型并进行转换。

我找到了一个“解决方法”并将其保存为 csv,然后再次加载。

有什么方法可以使用pandas read_csv 类型转换功能而不需要保存和加载文件?

'A': 0: nan,
      1: nan,
      2: nan,
      3: nan,
      4: nan,
      5: nan,
      6: nan,
      7: 'true',
      8: nan,
      9: 'true',
     'B': 0: nan,
      1: nan,
      2: nan,
      3: nan,
      4: nan,
      5: nan,
      6: nan,
      7: 'true',
      8: nan,
      9: 'true',
     'C': 0: 'CustomersData',
      1: 'CustomersData',
      2: 'CustomersData',
      3: 'CustomersData',
      4: 'CustomersData',
      5: 'CustomersData',
      6: 'CustomersData',
      7: 'TestData',
      8: 'CustomersData',
      9: 'CustomersData',
     'D': 0: '4014',
      1: '4014',
      2: '4014',
      3: '4014',
      4: '4014',
      5: '4014',
      6: '4014',
      7: '500',
      8: '4014',
      9: '500',
     'E': 0: '8',
      1: '8',
      2: '8',
      3: '8',
      4: '8',
      5: '8',
      6: '13',
      7: '13',
      8: '8',
      9: '13'

这是我正在做的事情:

df.to_csv('test.csv')
test_df = pd.read_csv('test.csv')
test_df.dtypes

仅当我使用此解决方法时,pandas read_csv 才会正确推断像“1”和“4044”这样的字符串为整数。 我试过 convert_dtypes() 将所有列都转换为字符串,infer_objects() 也没有做任何事情。

【问题讨论】:

当您转换为 csv 时,它可能会删除单引号,而当您读回它时, read_csv 会将它们作为整数。如果在创建数据框时删除单引号,convert_dtypes() 也会假定它们是整数。 @Jayvee 感谢您的评论,但实际上上述结果是一个长键值表/数据框的数据透视表。如何配置数据透视表以删除它们?实际上它转向了对象。请指教。 我不确定如何在数据透视表中执行此操作,但您始终可以使用 astype 在数据框中显式更改类型,例如 df['D'] = df['D '].astype(int) @Jayvee 但我不知道类型,这就是我需要 pandas 来推断这个系统中的类型的点。它将自动从数据库加载,转换为数据透视表,推断类型,填充缺失值......并执行所有其他逻辑。 【参考方案1】:

根据 cmets,有利于推断类型的实际过程是 to_csv,因为它去除了单引号。可能你可以使用一些底层的 to_csv 类和函数(DataFrameFormatter、DataFrameRenderer、CSVFormatter 等),但它会更多的代码和更多出错的风险。 您可以做的是写入和读取缓冲区,以避免 IO 开销。

d='A': 0: np.NaN,
      1: np.NaN,
      2: np.NaN,
      3: np.NaN,
      4: np.NaN,
      5: np.NaN,
      6: np.NaN,
      7: 'true',
      8: np.NaN,
      9: 'true',
     'B': 0: np.NaN,
      1: np.NaN,
      2: np.NaN,
      3: np.NaN,
      4: np.NaN,
      5: np.NaN,
      6: np.NaN,
      7: 'true',
      8: np.NaN,
      9: 'true',
     'C': 0: 'CustomersData',
      1: 'CustomersData',
      2: 'CustomersData',
      3: 'CustomersData',
      4: 'CustomersData',
      5: 'CustomersData',
      6: 'CustomersData',
      7: 'TestData',
      8: 'CustomersData',
      9: 'CustomersData',
     'D': 0: '4014',
      1: '4014',
      2: '4014',
      3: '4014',
      4: '4014',
      5: '4014',
      6: '4014',
      7: '500',
      8: '4014',
      9: '500',
     'E': 0: '8',
      1: '8',
      2: '8',
      3: '8',
      4: '8',
      5: '8',
      6: '13',
      7: '13',
      8: '8',
      9: '13'

df=pd.DataFrame(d)

from io import StringIO

buffer=StringIO()
df.to_csv(buffer, index=False)
df_new=pd.read_csv(StringIO(buffer.getvalue()))


df_new.dtypes

输出:

A    object
B    object
C    object
D     int64
E     int64
dtype: object

然后您可以使用 convert_types 来获得最佳推理:

df_new.convert_dtypes().dtypes

输出:

A    boolean
B    boolean
C     string
D      Int64
E      Int64
dtype: object

【讨论】:

以上是关于有没有办法从 pandas read_csv 中“提取”dtype 转换功能?的主要内容,如果未能解决你的问题,请参考以下文章

pandas使用read_csv函数随机从文件中读取N行数据pandas使用read_csv函数读取空格分割的文件(space)自定义设置sep参数

python pandas 中文件的读写——read_csv()读取文件

当我通过 skip_footer arg 时,Pandas read_csv 忽略列 dtypes

如何让 pandas.read_csv() 从 CSV 文件列中推断 datetime 和 timedelta 类型?

使用 pandas.read_csv 从 URL 读取压缩的 CSV 文件时出错

解决错误:pandas.read_csv() 报错 OSError: Initializing from file failed