這個問題已經被討論過。 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