【问题标题】:How to read csv without changing original datatypes in pandas如何在不更改熊猫原始数据类型的情况下读取 csv
【发布时间】:2018-11-09 14:41:25
【问题描述】:

我正在阅读 csv,我不希望将列的数据类型作为对象,它们应该是 int、float、str 等。

data = pd.read_csv(file_path+files, delimiter='\t', error_bad_lines=False)

data.dtypes:
  Time       object
  Code        int64
  Address     object
  dtype: object

有什么方法可以让我们在读取时从 csv 中读取数据类型:

预期:

data.dtypes:
  Time        int
  Code        int64
  Address     str

我有一个看起来像这样的数据框:

df:
    A     B    C
    abc   10   20
    def   30   50  
    cfg   90   60
    pqr   str  50
    xyz   75   56

我想删除列“B”不是“int”的行。由于 B 的 dtype 设置为 'object' 我无法这样做。

【问题讨论】:

  • 那么,时间的格式是什么?如果它是标准格式,那么您可以使用 parse_dates 参数,但文档提示您通常需要在导入 For non-standard datetime parsing, use pd.to_datetime after pd.read_csv 后处理此问题。此外,没有str 类型。该列需要为object
  • 这个问题我不清楚。 only 类型的 CSV 数据是...文本。因为 CSV 文件只是文本。其他任何东西都只是解析器的解释。我认为这就是@ALollz 的意思。

标签: python pandas dataframe


【解决方案1】:

您可以将dtype kwarg 提供给read_csv()。来自文档:

dtype : 类型名称或列的字典 -> 类型,默认无

数据或列的数据类型。例如。 {‘a’: np.float64, ‘b’: np.int32} 使用 str 或 object 以及合适的 na_values 设置来保留而不是解释 dtype。如果指定了转换器,则将应用它们代替 dtype 转换。

例如

data = pd.read_csv(..., dtype={'Time': np.int64})

编辑:正如@ALollz 指出的那样,如果无法转换指定列中的数据,这将中断。如果您想使用不同位数读取数据(例如 np.int32 而不是 np.int64),通常会使用它。

您可以在 DataFrame 上使用 df['Time'].astype(int)ojbects 来诊断导致转换问题的数据。

【讨论】:

  • 但问题是,如果.read_csv 尚未将列解析为数字,则几乎可以肯定列中存在非数字值。指定一个数字dtype 将您从一起解析文件。
  • 同意 - 如果转换不起作用,这将强制输入类型并中断。
  • 我不想明确设置数据类型。有什么方法可以从 csv 隐式推断数据类型?
  • @tejasshah 它已经做到了。如果推断不正确,您应该查看不属于正确类型的数据。您可以使用df['Time'].astype(int) 来诊断问题。
  • @Alex,这正是我的情况。查看已编辑的问题
【解决方案2】:

您可以轻松地将列转换为数字类型:

data['Time'] = data['Time'].astype(int)

你的字符串字段的 dtype 虽然是一个对象,因为它是一个字符串对象。我相信有可能创建一个明确为字符串的新 dtype,但我不知道这样做有什么好处。

对于您编辑的问题,您要做的是定义一个转换器(因为您的文件没有为该列定义的数据类型)

import numpy as np

def col_fixer(x):
    try:
        return int(x)
    except ValueError:
        return np.nan

data = pd.read_csv(file_path+files, delimiter='\t', converters=dict(B=col_fixer))

然后,您可以随意丢弃带有 NA 的行。

【讨论】:

  • 我不想明确设置数据类型。有什么方法可以从 csv 隐式推断数据类型?
  • 它已经做到了。你的问题是你想撤消那个。
  • 在我的解决方案中试过,没有变化,仍然面临错误
  • 解决方案会将所有列转换为 int 吗?
  • 它将转换您告诉它转换的任何列。您提供的具体示例与我给您的具体答案正确配合;我可以使用data.dropna() 删除违规行。如果它不适合您,提供一个真实的问题示例可能会有所帮助。
【解决方案3】:

要绕过 Pandas 的错误类型推断,请使用 csv 阅读器将字符串提供给 DataFrame 构造函数。

with open('/tmp/test.csv', 'r') as fin:
    csv_data = io.StringIO(fin.read())
df = pd.DataFrame([*csv.DictReader(csv_data)])

【讨论】:

    【解决方案4】:
    #ex.csv 
    # -0.11566111265093704,0.7655813,0
    # 0.8792716084627679,0.82952684,1
    # 0.5744048344633055,0.8762405,2
    # -0.6245665678004078,0.24478662,3
    # -0.33955465349370706,-0.042879142,4
    
    curfile = pd.read_csv("ex.csv", dtype={0: np.float64, 1: np.float32, 2: int}, header=None)
    
    print(type(curfile.iloc[0,0]), type(curfile.iloc[0,1]), type(curfile.iloc[0,2]))
    
    # <class 'numpy.float64'> <class 'numpy.float32'> <class 'numpy.int32'>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-24
      • 1970-01-01
      • 2021-06-09
      • 2019-10-26
      • 1970-01-01
      • 2016-09-04
      • 1970-01-01
      • 2019-09-13
      相关资源
      最近更新 更多