更新列标题后,允许重复的列熊猫/刷新列dtypes

时间:2019-09-05 17:28:38

标签: python pandas pyarrow

我正在根据字符串数据创建一个数据框,该字符串的标题具有重复的列。由于熊猫默认情况下会在重复列的情况下检查自动重命名,因此会在每个重复列中添加“ .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

我遵循提到的here

解决方案
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 :('需要一个整数(got类型为str)','类型为a的对象的列转换失败')

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

df = df.astype(str)

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

我的数据文件的最终状态为Parquet,并且由于Parquet操作高度依赖于元数据,因此上述data_type不是预期的。

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

预期df:

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

> dtype('int64')

2 个答案:

答案 0 :(得分:0)

如果仅将列替换为非点/数字版本,则可以使用正则表达式和列表理解

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

答案 1 :(得分:0)

在第一个位置创建字符串时,我在标题行中添加了_counter,这使每个列标题都是唯一的,然后将其读入df之后,解析并从列名中删除了_counter。下面是代码:

formatted_data = "a_1|b_2|c_3|a_4\n1|xyz|3|4"

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

输出:

a_1   b_2   c_3   a_4
1     xyz   3     4

删除添加的 _counter

df.columns = df.columns.str.rsplit('_', 1).str[0]

输出:

a   b   c   a
1   xyz 3   4

如何创建 formatted_df 回答:每个案例可能会有所不同。对我来说,我是直接从文件中读取内容,因此在读取第一行时,我在管道之前添加了_counter