了解NumPy对字符串数据类型的解释

时间:2016-08-08 20:45:55

标签: python arrays string numpy

假设我有一个表示某些数据的字节对象,我想通过numpy将其转换为np.genfromtxt数组。在这种情况下,我无法理解如何处理字符串。让我们从以下开始:

from io import BytesIO
import numpy as np

text = b'test, 5, 1.2'
types = ['str', 'i4', 'f4']
np.genfromtxt(BytesIO(text), delimiter = ',', dtype = types)

这不起作用。它提出了

TypeError: data type not understood

如果我更改types以便types = ['c', 'i4', 'f4']

然后numpy调用返回

array((b't', 5, 1.2000000476837158), 
      dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<f4')])

所以它有效,但显然我只得到字符串的第一个字母。

如果我使用c8c16作为test的dtype,那么我会

array(((nan+0j), 5, 1.2000000476837158), 
      dtype=[('f0', '<c8'), ('f1', '<i4'), ('f2', '<f4')])

这是垃圾。我也尝试过使用aU,但没有成功。我如何让genfromtxt识别并将元素保存为字符串?

编辑:我假设ssue的一部分是这是一个bytes对象。但是,如果我改为使用普通字符串作为text,并使用StringIO而不是BytesIO,则genfromtxt会引发错误:

TypeError: Can't convert字节object to str implicitly

1 个答案:

答案 0 :(得分:0)

在我的Python3会话中:

In [568]: text = b'test, 5, 1.2'
# I don't need BytesIO since genfromtxt works with a list of
# byte strings, as from text.splitlines()

In [570]: np.genfromtxt([text], delimiter=',', dtype=None)
Out[570]: 
array((b'test', 5, 1.2), 
      dtype=[('f0', 'S4'), ('f1', '<i4'), ('f2', '<f8')])

如果留给自己的设备genfromtxt,则推断第一个字段应为S4 - 4个字符串字符。

我也可以明确表示类型:

In [571]: types=['S4', 'i4', 'f4']
In [572]: np.genfromtxt([text],delimiter=',',dtype=types)
Out[572]: 
array((b'test', 5, 1.2000000476837158), 
      dtype=[('f0', 'S4'), ('f1', '<i4'), ('f2', '<f4')])
In [573]: types=['S10', 'i', 'f']
In [574]: np.genfromtxt([text],delimiter=',',dtype=types)
Out[574]: 
array((b'test', 5, 1.2000000476837158), 
      dtype=[('f0', 'S10'), ('f1', '<i4'), ('f2', '<f4')])

In [575]: types=['U10', 'int', 'float']
In [576]: np.genfromtxt([text],delimiter=',',dtype=types)
Out[576]: 
array(('test', 5, 1.2), 
      dtype=[('f0', '<U10'), ('f1', '<i4'), ('f2', '<f8')])

我可以指定SU(unicode),但我还必须指定长度。我不认为genfromtxt允许它推断长度 - None类型除外。我必须深入研究代码,看看它是如何推断字符串长度的。

我也可以用np.array创建这个数组(通过使它成为子串的元组,并给出正确的dtype:

In [599]: np.array(tuple(text.split(b',')), dtype=[('f0', 'S4'), ('f1', '<i4'), ('f2', '<f8')])
Out[599]: 
array((b'test', 5, 1.2), 
      dtype=[('f0', 'S4'), ('f1', '<i4'), ('f2', '<f8')])