在Python 3中,我这样做:
s = StringIO(u"1,1.3,abcde\n2,1.3,test")
data = numpy.genfromtxt(s, dtype=[int,float,'U10'], delimiter=',', names=None)
我得到:
array([(1, 1.3, 'abcde'), (2, 1.3, 'test')],
dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', '<U10')])
我想获得一个没有以下名称的常规numpy数组:
array([[1, 1.3, 'abcde'],
[2, 1.3, 'test']])
有可能吗?
您得到的是一个“结构化数组”,它优于“常规数组”,因为它支持异构数据类型。您的两列是数字,但一列是文本,因此将数据折叠成没有结构的普通numpy.ndarray
并没有什么意义。但是,如果您愿意,可以:
numpy.array(data.tolist())
这将为您提供带有所有字符串的ndarray
:
array([['1', '1.3', 'abcde'],
['2', '1.3', 'test']], dtype='<U32')
但是这很少是一个好主意。如果我们有更多的背景信息,我们也许可以提出更好的总体方法。
带有文本列表:
In [338]: txt = '''1, 1.3, abcde
...: 2, 1.3, def'''.splitlines()
结构化数组:
In [339]: np.genfromtxt(txt, dtype=None, delimiter=',', encoding=None)
Out[339]:
array([(1, 1.3, ' abcde'), (2, 1.3, ' def')],
dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', '<U6')])
试图指定对象-每个项目都有自己的类型:
In [340]: np.genfromtxt(txt, dtype=object, delimiter=',', encoding=None)
Out[340]:
array([[b'1', b' 1.3', b' abcde'],
[b'2', b' 1.3', b' def']], dtype=object)
它不会尝试将任何字符串转换为数字。
converters
可以正确转换列,但由于某些原因仍会生成结构化数组:
In [341]: np.genfromtxt(txt, dtype=object, delimiter=',', encoding=None, convert
...: ers={0:int, 1:float})
Out[341]:
array([(1, 1.3, b' abcde'), (2, 1.3, b' def')],
dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', 'O')])
但是您可以通过列表将结构化数组转换为对象dtype:
In [346]: np.genfromtxt(txt, dtype=None, delimiter=',', encoding=None)
Out[346]:
array([(1, 1.3, ' abcde'), (2, 1.3, ' def')],
dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', '<U6')])
In [347]: np.array(_.tolist(), object)
Out[347]:
array([[1, 1.3, ' abcde'],
[2, 1.3, ' def']], dtype=object)
[另一种选择是您自己分割行,以建立列表列表。 genfromtxt
正在这样做,只需要再少一些花哨的技巧。
In [357]: lines=[]
...: for line in txt:
...: i = line.split(',')
...: x = (int(i[0]), float(i[1]), i[2].strip())
...: lines.append(x)
In [358]: lines
Out[358]: [(1, 1.3, 'abcde'), (2, 1.3, 'def')]
In [359]: np.array(lines,object)
Out[359]:
array([[1, 1.3, 'abcde'],
[2, 1.3, 'def']], dtype=object)
但是请注意,您不能在该对象数组,数字数组甚至结构化数组的数字字段上进行数学运算。