【问题标题】:pandas fail to infer str type with double quotation markspandas 无法用双引号推断 str 类型
【发布时间】:2016-03-26 12:44:02
【问题描述】:

我想从pandas.read_csv() 的csv 文件中导入数据。我的数据的一种类型是带有“”的字符串(但这些字符串是数字表示类别)。我发现 pandas 无法将字符串推断为"object" 类型,而是将它们推断为int64。请参阅以下示例:

a.csv

uid, f_1, f_2
1,   "1", 1.1
2,   "2", 2.3
3,   "0", 4.8

pandas.read_csv('a.csv').dtypes 给出以下输出:

uid:int64
f_1:int64
f_2:float64

f_1 的类型被推断为'int64' 而不是'object'

但是,如果我将 a.csv 中的所有 " 替换为 ',则 f_1 可以正确推断为 'object'。如何在不修改'a.csv' 的情况下防止错误推理?另一个问题是,为什么 pandas 将字符串推断为 'object' 类型而不是 'str' 类型?

【问题讨论】:

  • 对于后者,numpy 没有 str 类型,只有特定长度的 str。由于通常列是混合长度的,pandas 使用对象作为字符串来提高数据存储的效率。前者可能是bug,请发到github上:github.com/pydata/pandas/issues
  • 欢迎来到 Stackoverflow。您可以查看tour,网站的运作方式。

标签: python csv pandas dataframe


【解决方案1】:

我认为您需要在read_csv 中添加参数skipinitialspace

skipinialspace : boolean,默认为 False,分隔符后跳过空格

测试:

import pandas as pd
import numpy as np
import io


temp=u"""uid, f_1, f_2
1,  "1", 1.19
2,  "2", 2.3
3,  "0", 4.8"""

print pd.read_csv(io.StringIO(temp))
   uid    f_1   f_2
0    1    "1"  1.19
1    2    "2"  2.30
2    3    "0"  4.80

#doesn't work dtype    
print pd.read_csv(io.StringIO(temp), dtype= {'f_1': np.int64}).dtypes
uid       int64
 f_1     object
 f_2    float64
dtype: object

print pd.read_csv(io.StringIO(temp), skipinitialspace=True).dtypes
uid      int64
f_1      int64
f_2    float64
dtype: object

如果您想从列f_1 中删除第一个和最后一个字符",请使用converters

import pandas as pd
import io


temp=u"""uid, f_1, f_2
1,  "1", 1.19
2,  "2", 2.3
3,  "0", 4.8"""

print pd.read_csv(io.StringIO(temp))
   uid    f_1   f_2
0    1    "1"  1.19
1    2    "2"  2.30
2    3    "0"  4.80

#remove "
def converter(x):
    return x.strip('"')

#define each column
converters={'f_1': converter}

df = pd.read_csv(io.StringIO(temp), skipinitialspace=True, converters = converters)
print df
   uid f_1   f_2
0    1   1  1.19
1    2   2  2.30
2    3   0  4.80
print df.dtypes
uid      int64
f_1     object
f_2    float64
dtype: object

如果您需要将integerf_1 转换为string,请使用dtype

import pandas as pd
import io


temp=u"""uid, f_1, f_2
1,  1, 1.19
2,  2, 2.3
3,  0, 4.8"""

print pd.read_csv(io.StringIO(temp)).dtypes
uid       int64
 f_1      int64
 f_2    float64
dtype: object

df = pd.read_csv(io.StringIO(temp), skipinitialspace=True, dtype = {'f_1' : str })

print df
   uid f_1   f_2
0    1   1  1.19
1    2   2  2.30
2    3   0  4.80
print df.dtypes
uid      int64
f_1     object
f_2    float64
dtype: object

注意:不要忘记将io.StringIO(temp) 更改为a.csv

解释str vs objecthere

【讨论】:

  • 感谢您的工作!我发现很奇怪,当我使用您的小样本时,它可以工作,但是当 pandas 尝试加载更大的文件(在我的情况下为 200MB 或更多)时,即使我尝试了skipinitialspace=True,它仍然失败。但是dtype=... 有效,所以无论如何,感谢您的建议。
  • 如果有帮助,您可以accept我的回答。谢谢。
【解决方案2】:

您可以通过在 dtype 可选参数中提供列名或字典来强制在 read_csv 调用中进行推理,请参阅 read_csv 上的 pandas 文档。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-29
    相关资源
    最近更新 更多