首页 > 解决方案 > 更新列标题时允许重复列熊猫/刷新列dtypes

问题描述

我正在从字符串数据中创建一个数据框,其标题有重复的列。由于 pandas 默认检查在重复列的情况下自动重命名,它会为每个重复添加“.1、.2 等”后缀。

formatted_data = "a|b|c|a\n1|xyz|3|4"

final_data = StringIO(formatted_data)

df = pd.read_csv(final_data, sep='|')

输出df:

a    b    c    a.1
1    xyz  3    4

我按照这里提到的解决方案

df = pd.read_csv(final_data, sep='|', header=None)

df = df.rename(columns=df.iloc[0], copy=False).iloc[1:].reset_index(drop=True)

输出 df 符合预期,但它与元数据混淆,强制所有列的 dtype 为dtype('O')。这个 dtype 对我的转换代码有级联影响,我从transformed_df 创建了一个arrow_table。

arrow_table = pa.Table.from_pandas(df, preserve_index=False)

它出错:pyarrow.lib.ArrowTypeError: ('需要一个整数(类型为 str)','a 列类型为对象的转换失败')

为了解决上述错误,在创建表之前,我将 df 类型分配给 str & 问题得到解决:

df = df.astype(str)

但是表的元数据存储所有列的'pandas_type': "unicode"

我的数据文件的最终状态是 parquet & 由于 parquet 操作高度依赖于元数据,上述 data_type 不是预期的。

是否有 pandas 内置选项或解决方法来获得预期的 df 而不会丢失 dtype 或根据值自动重新分配 dtype:

预期的df:

a    b    c    a
1    xyz  3    4
df.a.dtype

> dtype('int64')

标签: pythonpandaspyarrow

解决方案


如果您只是用非点/编号版本替换列,则可以使用正则表达式和列表理解

import re

df

    a   b   c   a.1 test.1abc
0   1   xyz 3   4   5

df.dtypes

a       int64
b      object
c       int64
a.1     int64
dtype: object

df.columns=[re.sub(r'(\.\d\b)','',i) for i in df.columns]    

df

    a   b   c   a   test.1abc
0   1   xyz 3   4   5

df.dtypes

a       int64
b      object
c       int64
a.1     int64
dtype: object

推荐阅读