18

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

我正在使用 .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()

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

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

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

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

4

4 回答 4

17

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

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

csv.QUOTE_NONNUMERIC:指示阅读器将所有未引用的字段转换为浮点类型。

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

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

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

于 2016-08-29T02:25:36.090 回答
4

将一堆字符串转换为浮点数时,应该使用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...    
于 2013-09-18T16:32:42.413 回答
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())

至于最简单的方法,那么我建议您查看xlrd,xlwt模块,就我个人而言,我总是很难处理所有不同的 CSV 格式。

于 2013-09-18T16:30:12.583 回答
0
for y in x:
                print type(float(y)),

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

y = 浮动(y)

更像你正在寻找的东西 - 你必须修改对象。

于 2013-09-18T16:34:49.250 回答