我正在尝试使用numpy.genfromtxt
读取csv文件,但有些字段是包含逗号的字符串。字符串是引号,但是numpy没有将引号识别为定义单个字符串。例如,使用't.csv'中的数据:
2012, "Louisville KY", 3.5
2011, "Lexington, KY", 4.0
代码
np.genfromtxt('t.csv', delimiter=',')
产生错误:
ValueError:检测到一些错误! 第2行(有4列而不是3列)
我正在寻找的数据结构是:
array([['2012', 'Louisville KY', '3.5'],
['2011', 'Lexington, KY', '4.0']],
dtype='|S13')
查看文档,我没有看到任何处理此问题的选项。有没有办法用numpy做,或者我只需要用csv
模块读取数据然后将其转换为numpy数组?
答案 0 :(得分:20)
您可以使用pandas(成为使用科学python中的数据帧(异构数据)的默认库)。 read_csv
可以处理这个问题。来自文档:
quotechar:string
The character to used to denote the start and end of a quoted item. Quoted items can include the delimiter and it will be ignored.
默认值为"
。一个例子:
In [1]: import pandas as pd
In [2]: from StringIO import StringIO
In [3]: s="""year, city, value
...: 2012, "Louisville KY", 3.5
...: 2011, "Lexington, KY", 4.0"""
In [4]: pd.read_csv(StringIO(s), quotechar='"', skipinitialspace=True)
Out[4]:
year city value
0 2012 Louisville KY 3.5
1 2011 Lexington, KY 4.0
这里的诀窍是你还必须使用skipinitialspace=True
来处理逗号分隔符之后的空格。
除了强大的csv阅读器之外,我还强烈建议将pandas与你拥有的异构数据一起使用(你给出的numpy中的示例输出都是字符串,尽管你可以使用结构化数组)。
答案 1 :(得分:11)
附加逗号的问题np.genfromtxt
没有解决这个问题。
一个简单的解决方案是将带有csv.reader()
的文件从python的csv模块读入列表,然后根据需要将其转储到numpy数组中。
如果你真的想使用np.genfromtxt
,请注意它可以使用迭代器而不是文件,例如np.genfromtxt(my_iterator, ...)
。因此,您可以将csv.reader
包装在迭代器中并将其提供给np.genfromtxt
。
那会是这样的:
import csv
import numpy as np
np.genfromtxt(("\t".join(i) for i in csv.reader(open('myfile.csv'))), delimiter="\t")
这实际上只是用标签替换了相应的逗号。
答案 2 :(得分:4)
如果你正在使用numpy,你可能想使用numpy.ndarray。这会给你一个numpy.ndarray:
import pandas
data = pandas.read_csv('file.csv').as_matrix()
Pandas将正确处理“Lexington,KY”案件
答案 3 :(得分:2)
创造一个更好的功能,结合标准csv
module和Numpy的recfromcsv
的力量。例如,csv
模块可以很好地控制和自定义方言,引号,转义字符等,您可以将其添加到下面的示例中。
下面的示例genfromcsv_mod
函数读入一个类似于Microsoft Excel看到的复杂CSV文件,其中可能包含引用字段中的逗号。在内部,该函数有一个生成器函数,它使用制表符分隔符重写每一行。
import csv
import numpy as np
def recfromcsv_mod(fname, **kwargs):
def rewrite_csv_as_tab(fname):
with open(fname, 'rb') as fp:
reader = csv.reader(fp)
for row in reader:
yield '\t'.join(row)
return np.recfromcsv(rewrite_csv_as_tab(fname), delimiter='\t', **kwargs)
# Use it to read a CSV file into a record array
x = recfromcsv_mod('t.csv', case_sensitive=True)