【问题标题】:Python 3 - Read csv file with type conversionPython 3 - 使用类型转换读取 csv 文件
【发布时间】:2015-03-17 21:22:37
【问题描述】:

我有两个问题:

a) Python csv 模块无法正确处理特定的 csv 文件

我在database.csv中有以下数据

"AAAAAAAA"        ,  5.4817,    0.0000,    0.0000,    0.0000,   65.8370
"n,m-BBBBBBBBB"   ,  1.7897,  675.3787, 1234.7865,   47.0000,   42.0070

请注意,双引号和逗号之间有空格。 我使用以下脚本读取文件,第一列将被解码为"AAAAAAAA ",而不是"AAAAAAAA"

import csv

def read_csv_data(path):
  with open(path, 'rU') as f:
    f_csv = csv.reader(f)
    for row in f_csv:
      yield row

for row in read_csv_data('database.csv'):
  print(row)

输出是

['AAAAAAAA        ', '  5.4817', '    0.0000', '    0.0000', '    0.0000', '   65.8370']
['n,m-BBBBBBBBB   ', '  1.7897', '  675.3787', ' 1234.7865', '   47.0000', '   42.0070']

要删除空格,我会这样做

import csv

def read_csv_data(path):
  col_type = [str, float, float, float, float, float]
  with open(path, 'rU') as f:
    f_csv = csv.reader(f)
    for row in f_csv:
      row = tuple(cast(val.strip()) for cast, val in zip(col_type, row))
      yield row

for row in read_csv_data('database.csv'):
  print(row)

现在是输出

('AAAAAAAA', 5.4817, 0.0, 0.0, 0.0, 65.8370)
('n,m-BBBBBBBBB', 1.7897, 675.3787, 1234.7865, 47.0, 42.007)

b) 使用 namedtuple 将 csv 数据读入内存

使用相同的 csv 文件 database.csv,我使用另一个脚本:

import csv
from collections import namedtuple

def read_csv_data(path):
  col_type = [str, float, float, float, float, float]
  Gas = namedtuple("Gas", ["gas", "sf", "h1", "h2", "h3", "m"])
  with open(path, 'rU') as f:
    f_csv = csv.reader(f)
    for row in f_csv:
      row = list(cast(val.strip()) for cast, val in zip(col_type, row))
      for row2 in map(Gas._make, row):
        yield row2


  for row in read_csv_data('database.csv'):
    print(row)

错误是

Traceback (most recent call last):
  File "read_dict.py", line 17, in <module>
    for row in read_csv_data('database.csv'):
  File "read_dict.py", line 13, in read_csv_data
    for row2 in map(Gas._make, row):
  File "<string>", line 21, in _make
TypeError: Expected 6 arguments, got 8

【问题讨论】:

    标签: python csv type-conversion namedtuple


    【解决方案1】:

    代替

    for row2 in map(Gas._make, row):
        yield row2
    

    你只是想要

    yield Gas._make(row)
    

    现在,您正在遍历 row 中的每个元素并在其上调用 Gas._make。这就是为什么你得到“预期 6 个参数,得到 8 个”的原因——你试图用 "AAAAAAAA" 创建一个 Gas 实例。

    改变这个之后,输出是

    Gas(gas='AAAAAAAA', sf=5.4817, h1=0.0, h2=0.0, h3=0.0, m=65.837)
    Gas(gas='n,m-BBBBBBBBB', sf=1.7897, h1=675.3787, h2=1234.7865, h3=47.0, m=42.007)
    

    PS:对于 Python 3,您应该使用 newline="" 打开文件以与 csv 一起使用,请参阅 here

    【讨论】:

    • 太棒了!谢谢。
    • 对于问题a),我感觉csv模块不能处理这种csv文件。我试过quoting=csv.QUOTE_NONNUMERICskipinitialspace=True
    • 我将 csv 文件 database.csv 导入 Microsoft Excel,包括尾随空格。这意味着它被认为是一个有效的 csv 文件。
    猜你喜欢
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    相关资源
    最近更新 更多