在导入的.csv中将字符串更改为Floats

时间:2013-09-18 16:26:10

标签: python string excel csv import

我无法快速解决问题的快速提问:

我正在使用.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'>"。但这实际上并没有将每个元素更改为float,也没有将for循环设置为执行float(y)(类型测试为每个元素返回'string')。

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

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

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

4 个答案:

答案 0 :(得分:12)

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

首先,您询问 &#34;如何将字符串转换为浮点数,在csv import&#34; 。答案是根据csv doc

打开csv.reader(..., quoting=csv.QUOTE_NONNUMERIC)
  

csv.QUOTE_NONNUMERIC:指示读者转换所有未引用的内容   字段以键入float。

如果您将所有未加引号的字段(整数,浮点数,文本,布尔等)转换为浮点数,这是有效的,这通常是一个糟糕的主意,原因很多(布尔值中缺少或NA值或因子会默默地压抑)。而且它显然会在未加引号的文本字段上失败(抛出异常)。因此它很脆弱,需要try..catch保护。

然后您问: &#39;我认为整体问题实际上只是&#34;什么是在.csv或excel中读取,组织和合成数据的最简单方法使用Python格式?&#34;&#39; 使用csv.reader(..., quoting=csv.QUOTE_NONNUMERIC)

打开蹩脚的csv.reader解决方案

但正如@geoffspear正确回复了&#39;答案你的整体问题&#34;可能是&#34; Pandas&#34;,虽然它有点模糊。&#39;

答案 1 :(得分:3)

尝试类似以下内容

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格式。

答案 2 :(得分: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 :(得分:0)

for y in x:
                print type(float(y)),

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

y = float(y)

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