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