【问题标题】:ValueError: could not convert string to float---how to convert a list of lists of strings into a numpy array type float?ValueError:无法将字符串转换为浮点数---如何将字符串列表转换为 numpy 数组类型浮点数?
【发布时间】:2018-09-19 14:07:08
【问题描述】:

看起来我在 Python3.x 中有一个格式错误的 numpy 数组——它被保存为字符串列表的列表。

foo = [[7.0352220e-01 5.3130367e-06 1.5167372e-05 1.0797821e-06]
  [1.3130367e-06 2.4584832e-01 2.2375602e-05 7.3299240e-06] [7.2646574e-06 7.1252006e-06 3.0184277e-01 ... 1.0048618e-05 3.1828706e-06 1.0196264e-06]..]

尝试将此数据作为 np.float32 读入 numpy 数组时出现以下错误:

np.asarray(foo, dtype=np.float32)

错误:

ValueError: could not convert string to float:[[7.0352220e-01 5.3130367e-06 1.5167372e-05 1.0797821e-06][1.3130367e-06 2.4584832e-01 2.2375602e-05 7.3299240e-06] [7.2646574e-06 7.1252006e-06 3.0184277e-01 ... 1.0048618e-05 3.1828706e-06 1.0196264e-06]..]

我尝试将每个列表元素显式转换为浮点数,如下所示:

try2 = np.asarray(map(np.float32, foo))

但它卡在一个支架上:

ValueError: could not convert string to float: [

将字符串列表转换为 numpy 数组的推荐方法是什么,输入 float?

【问题讨论】:

  • 在map之前,对每个元素使用split。
  • foo 到底是什么?错误表明它是一个字符串。如果它确实是一个嵌套的字符串列表,并且单独的字符串是有效的浮点表示,那么您的 asarray 将可以正常工作。问题是它甚至不是列表的有效字符串表示形式——它缺少JSON 需要的逗号。正如您所注意到的,[] 搞砸了对split 的简单尝试。没有一种方法可以解决这个问题。您可以通过各种方式编辑字符串以使其可解析 - 插入逗号、删除 [] 等。
  • 另一件事——看那些'...'。那是缺少数据。这看起来像一个 numpy 数组的字符串表示。您无法从此字符串中恢复该数组。

标签: python string python-3.x numpy floating-point


【解决方案1】:

如果您用逗号替换空格,您可以使用json.loads 将字符串作为列表读取,并将其传递给np.asarray

import json
import numpy as np

foo = "[[7.0352220e-01 5.3130367e-06 1.5167372e-05 1.0797821e-06] \
[1.3130367e-06 2.4584832e-01 2.2375602e-05 7.3299240e-06]]"

a = np.asarray(json.loads(foo.replace(" ", ",")), dtype=np.float32)
print(a)
#array([[7.0352220e-01, 5.3130367e-06, 1.5167372e-05, 1.0797821e-06],
#       [1.3130367e-06, 2.4584832e-01, 2.2375602e-05, 7.3299240e-06]])

print(a.dtype)
#float32

这假设值之间恰好有 1 个空格。如果不是这样,您可以使用re.sub 将多个空格替换为逗号:

import re
a = np.asarray(json.loads(re.sub("\s+", ",", foo)))
#array([[7.0352221e-01, 5.3130366e-06, 1.5167372e-05, 1.0797821e-06],
#       [1.3130367e-06, 2.4584831e-01, 2.2375601e-05, 7.3299238e-06]],
#      dtype=float32)

【讨论】:

    【解决方案2】:

    据我所见,np.asarray() 只有在 dtype 具有与初始数据类型不同的数据类型时才有效。请尝试删除该参数,看看它是否有效。

    【讨论】:

      【解决方案3】:

      您的字符串数据是如何形成的?可能最简单的方法是使用 split() 并遍历列表。对我有用的示例(字符串列表列表):

      foo = [['7.0352220e-01 5.3130367e-06 1.5167372e-05 1.0797821e-06'],
             ['7.0352220e-01 5.3130367e-06 1.5167372e-05 1.0797821e-06']]
      arr = np.array([[value.split() for value in row][0] for row in foo], dtype='<f8')
      

      (注意:[0] 用作 split 自己创建一个列表。您可以使用 np.reshape 替代)

      编辑:如果它是字符串表示形式(不是 OP 中所述的字符串列表):

      foo = '[[7.0352220e-01 5.3130367e-06 1.5167372e-05 1.0797821e-06][7.0352220e-01 5.3130367e-06 1.5167372e-05 1.0797821e-06]'
      arr=np.array([line.split() for line in foo.replace('[','').replace(']]','').split(']')], dtype='<f8')
      

      【讨论】:

      • 不是字符串列表,是列表的字符串表示
      • 我没有问这个问题。
      【解决方案4】:

      给定:

      foo = [['7.0352220e-01 5.3130367e-06 1.5167372e-05 1.0797821e-06'],
             ['1.3130367e-06 2.4584832e-01 2.2375602e-05 7.3299240e-06'], 
             ['7.2646574e-06 7.1252006e-06 3.0184277e-01 1.0048618e-05']]
      

      试试这个分割每个字符串

      foo = [row[i].split() for row in foo for i in range(len(foo[0]))]
      

      这用于将类型更改为浮点数。

      foo = [[float(row[i]) for i in range(len(foo[0]))] for row in foo]
      
      print(type(foo[0][1]))
      
      >> float
      

      然后把它变成一个numpy数组:

      foo = np.array(foo)
      
      print(type(foo[0][1]))
      
      >> numpy.float64
      

      【讨论】:

      • 您的答案符合单词描述,但不符合示例或错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-23
      • 2018-06-13
      • 2013-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多