使用numpy.loadtxt加载包含float和string的文本文件

Vei*_*pse 23 python numpy python-2.7 python-3.x

我有一个文本文件data.txt,其中包含:

5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
5.8,2.7,4.1,1.0,Iris-versicolor
6.2,2.2,4.5,1.5,Iris-versicolor
6.4,3.1,5.5,1.8,Iris-virginica
6.0,3.0,4.8,1.8,Iris-virginica
Run Code Online (Sandbox Code Playgroud)

如何使用numpy.loadtxt()这样加载这些数据,以便在加载后获得NumPy数组[['5.1' '3.5' '1.4' '0.2' 'Iris-setosa'] ['4.9' '3.0' '1.4' '0.2' 'Iris-setosa'] ...]

我试过了

np.loadtxt(open("data.txt"), 'r',
           dtype={
               'names': (
                   'sepal length', 'sepal width', 'petal length',
                   'petal width', 'label'),
               'formats': (
                   np.float, np.float, np.float, np.float, np.str)},
           delimiter= ',', skiprows=0)
Run Code Online (Sandbox Code Playgroud)

unu*_*tbu 39

如果你使用np.genfromtxt,你可以指定dtype=None,它会告诉genfromtxt你智能地猜测每列的dtype.最方便的是,它减轻了指定字符串列所需字节数的麻烦.(通过指定例如np.str,省略字节数不起作用.)

In [58]: np.genfromtxt('data.txt', delimiter=',', dtype=None, names=('sepal length', 'sepal width', 'petal length', 'petal width', 'label'))
Out[58]: 
array([(5.1, 3.5, 1.4, 0.2, 'Iris-setosa'),
       (4.9, 3.0, 1.4, 0.2, 'Iris-setosa'),
       (5.8, 2.7, 4.1, 1.0, 'Iris-versicolor'),
       (6.2, 2.2, 4.5, 1.5, 'Iris-versicolor'),
       (6.4, 3.1, 5.5, 1.8, 'Iris-virginica'),
       (6.0, 3.0, 4.8, 1.8, 'Iris-virginica')], 
      dtype=[('sepal_length', '<f8'), ('sepal_width', '<f8'), ('petal_length', '<f8'), ('petal_width', '<f8'), ('label', 'S15')])
Run Code Online (Sandbox Code Playgroud)

如果您确实想要使用np.loadtxt,那么只需要进行最少的更改即可修复代码,您可以使用:

np.loadtxt("data.txt",
   dtype={'names': ('sepal length', 'sepal width', 'petal length', 'petal width', 'label'),
          'formats': (np.float, np.float, np.float, np.float, '|S15')},
   delimiter=',', skiprows=0)
Run Code Online (Sandbox Code Playgroud)

主要区别在于简单地np.str改为|S15(一个15字节的字符串).

还要注意 open("data.txt"), 'r'应该open("data.txt", 'r').但是因为np.loadtxt可以接受文件名,所以根本不需要使用open.

  • 当我尝试这个时,我的字符串以字节文字形式读入,例如b'ADT1_YEAST'.我是否必须手动转换它们,或者有没有办法让它像你的例子一样读取字符串? (2认同)
  • @mattgabor:如果你将'dtype = None`改为'dtype = ['<f8','<f8','<f8','<f8','U15']`那么`np.genfromtxt`将加载最后一列为`str`s而不是`byte`s. (2认同)

mau*_*uve 19

似乎将数字和文本保持在一起已经给你带来了很多麻烦 - 如果你最终决定将它们分开,我的解决方法是:

values = np.loadtxt('data', delimiter=',', usecols=[0,1,2,3])
labels = np.loadtxt('data', delimiter=',', usecols=[4])
Run Code Online (Sandbox Code Playgroud)

  • 对于标签,我认为您需要添加`dtype = np.str`才能使其正常工作.否则,你将得到`ValueError:无法将字符串转换为float:Iris-setosa`或类似的东西. (5认同)
  • np.genfromtxt 总体上更健壮,自从我最初回答这个问题以来,它让我省了很多心痛 (2认同)
  • 并考虑研究熊猫。您将永远不会再使用 .loadtxt 或 .genfromtxt! (2认同)