这个问题已经被讨论过。 loadtxt
(或genfromtxt
)中没有任何参数可以满足您的需求。换句话说,它不是引号敏感的。 python
csv
模块具有某种报价意识。 pandas
阅读器也是引用意识。
但是在将它们传递给loadtxt
之前处理这些行是完全可以接受的。所有的功能需求都是可迭代的 - 一次可以提供一条线。这可以是文件,行列表或生成器。
一个简单的处理器只会用一些其他字符替换引号内的逗号。或用您选择的分隔符替换引号外的那些。它不一定是想做这项工作。
Using numpy.genfromtxt to read a csv file with strings containing commas
例如:
txt = """10,"Apple, Banana",20
30,"Pear, Orange",40
50,"Peach, Mango",60
"""
def foo(astr):
# replace , outside quotes with ;
# a bit crude and specialized
x = astr.split('"')
return ';'.join([i.strip(',') for i in x])
txt1 = [foo(astr) for astr in txt.splitlines()]
txtgen = (foo(astr) for astr in txt.splitlines()) # or as generator
# ['10;Apple, Banana;20', '30;Pear, Orange;40', '50;Peach, Mango;60']
np.genfromtxt(txtgen, delimiter=';', dtype=None)
生产:
array([(10, 'Apple, Banana', 20), (30, 'Pear, Orange', 40),
(50, 'Peach, Mango', 60)],
dtype=[('f0', '<i4'), ('f1', 'S13'), ('f2', '<i4')])
我没有重视np.fromregex
之前。与genfromtxt
相比,它非常简单。与我的样品txt
使用我不得不使用一个字符串缓冲区:
s=StringIO.StringIO(txt)
np.fromregex(s, r'(\d+),"(.+)",(\d+)', dtype='i4,S20,i4')
它的行动提炼到:
pat=re.compile(r'(\d+),"(.+)",(\d+)'); dt=np.dtype('i4,S20,i4')
np.array(pat.findall(txt),dtype=dt)
它读取整个文件(f.read()
),并做了findall
应该产生像这样的列表:
[('10', 'Apple, Banana', '20'),
('30', 'Pear, Orange', '40'),
('50', 'Peach, Mango', '60')]
元组列表正是结构化数组需要的。
没有花哨的处理,错误检查或过滤注释行。只是模式匹配,然后是数组构造。
我的两个foo
和fromregex
承担数的特定序列和引用字符串。 csv.reader
可能是最简单的通用报价阅读器。 join
是必需的,因为reader
产生一个列表清单,而genfromtxt
需要一个可迭代的字符串(它自己的'拆分')。
from csv import reader
s=StringIO.StringIO(txt)
np.genfromtxt((';'.join(x) for x in reader(s)), delimiter=';', dtype=None)
生产
array([(10, 'Apple, Banana', 20), (30, 'Pear, Orange', 40),
(50, 'Peach, Mango', 60)],
dtype=[('f0', '<i4'), ('f1', 'S13'), ('f2', '<i4')])
或者在下面的fromregex
例如,reader
输出也可以变成一个元组列表,并给np.array
直接:
np.array([tuple(x) for x in reader(s)], dtype='i4,S20,i4')
你使用Python的CSV模块加载试过? – Marcin 2015-02-11 00:20:23