【问题标题】:Changing strings to floats in an imported .csv在导入的 .csv 中将字符串更改为浮点数
【发布时间】:2013-09-23 12:32:56
【问题描述】:

针对我未能快速解决的问题的快速问题:

我正在使用 .csv 文件,但似乎找不到将字符串转换为浮点数的简单方法。这是我的代码,

import csv

def readLines():
    with open('testdata.csv', 'rU') as data:
        reader = csv.reader(data)
        row = list(reader)
        for x in row:
            for y in x:
                print type(float(y)),
readLines()

如你所见,它当前会打印变量 row 中 x 组列表中每个 y 元素的类型;这会产生一长串"<type 'float'>"。但这实际上并没有将每个元素更改为浮点数,也不会将 for 循环设置为执行 float(y)(类型测试为每个元素返回“字符串”)。

我也尝试了literal_eval,但也失败了。将列表元素更改为浮点数的唯一方法是使用列表解析或手动创建一个新列表,但这会丢失每个列表的原始格式(作为一个较大列表中一组元素的列表)。

我想整个问题实际上只是“使用 Python 读取、组织和合成 .csv 或 excel 格式的数据的最简单方法是什么?”

提前感谢那些有礼貌/知识渊博的人提供帮助。

【问题讨论】:

  • type 不会改变变量的类型,它只是返回变量的类型。一旦你将变量转换为浮点数,你需要就地赋值
  • 也许你想要y = float(y)
  • 你的“整体问题”的答案可能是“熊猫”,虽然有点模糊。
  • 首先你似乎问“如何在 csv 导入时将字符串转换为浮点数”,然后你将其变形为 '我想整体问题真的只是“使用 Python 以 .csv 或 excel 格式读取、组织和合成数据的最简单方法是什么?”特别限制我们使用import csv 与使用pandas 不同。本质上,内置 csv 模块已损坏,不应在任何包含一个或多个文本或分类字段的非玩具数据集上使用。使用熊猫。

标签: python string csv import floating-point


【解决方案1】:

你说得对,Python 的内置 csv 模块在处理混合数据类型方面非常原始,在导入时进行所有类型转换,甚至在那个时候有一个非常严格的选项菜单,这将破坏大多数真实世界的数据集(不一致的引用和转义,布尔值和因子中的缺失或不完整值,不匹配的 Unicode 编码导致字段内的幻引号或转义字符,不完整的行将导致异常)。修复 csv 导入是 pandas 的无数好处之一。因此,您的最终答案确实是停止使用内置 csv 导入并开始使用 pandas。但是,让我们从字面意思开始回答您的问题。

首先您问“如何在 csv 导入时将字符串转换为浮点数”。答案是按照csv doc打开csv.reader(..., quoting=csv.QUOTE_NONNUMERIC)

csv.QUOTE_NONNUMERIC:指示读者转换所有未引用的 输入浮点数的字段。

如果您可以将所有未加引号的字段(整数、浮点数、文本、布尔值等)转换为浮点数,这很有效,由于许多原因,这通常是一个坏主意(布尔值或因子中的缺失或 NA 值会得到无声无息)。此外,它显然会在未引用的文本字段上失败(抛出异常)。所以它很脆弱,需要用try..catch保护。

然后你问:'我想整个问题实际上只是“使用 Python 读取、组织和合成 .csv 或 excel 格式的数据最简单的方法是什么?”' 蹩脚的 csv.reader 解决方案是用csv.reader(..., quoting=csv.QUOTE_NONNUMERIC)打开的

但正如@geoffspear 正确回答的那样'你的“整体问题”的答案可能是“熊猫”,尽管它有点模糊。'

【讨论】:

  • 在很长一段时间后回到这个问题,其中一些已经使用 pandas,这是我认为其他提问者应该首先看到的答案。
  • 感谢@userNaN。是的,这是从 10 年在 Python、csv builtin、pandas、R、Excel 和其他语言/包中导入 CSV 数据的痛苦经验中提炼出来的。当您使用带引号的、转义的和/或 Unicode 字段以及 NA 时,它会变得更加痛苦。 csv 简单地中断了,你必须找到更好的东西。
【解决方案2】:

将一堆字符串转换为浮点数时,应该使用try/except 来捕获错误:

def conv(s):
    try:
        s=float(s)
    except ValueError:
        pass    
    return s

print [conv(s) for s in ['1.1','bls','1','nan', 'not a float']] 
# [1.1, 'bls', 1.0, nan, 'not a float']

请注意,无法转换的字符串只是简单地通过而不更改。

csv 文件是文本文件,因此您应该使用类似的功能:

def readLines():
    def conv(s):
        try:
            s=float(s)
        except ValueError:
            pass    
        return s

    with open('testdata.csv', 'rU') as data:
        reader = csv.reader(data)
        for row in reader:
            for cell in row:
                y=conv(cell)
              # do what ever with the single float
         # OR
         # yield [conv(cell) for cell in row]  if you want to write a generator...    

【讨论】:

    【解决方案3】:
    for y in x:
                    print type(float(y)),
    

    float(y) 获取 y 的值并基于它返回一个浮点数。它不修改 y- 它返回一个新对象。

    y = float(y)

    更像你要找的东西——你必须修改对象。

    【讨论】:

      【解决方案4】:

      试试下面的方法

      import csv
      
      def read_lines():
          with open('testdata.csv', 'rU') as data:
              reader = csv.reader(data)
              for row in reader:
                  yield [ float(i) for i in row ]
      
      for i in read_lines():
          print(i)
      
      # to get a list, instead of a generator, use
      xy = list(read_lines())
      

      至于最简单的方法,那么我建议您查看xlrdxlwt 模块,我个人总是很难处理各种不同的 CSV 格式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-31
        • 2020-04-22
        • 1970-01-01
        • 1970-01-01
        • 2019-01-07
        • 1970-01-01
        • 2018-01-11
        • 2020-02-08
        相关资源
        最近更新 更多