使用numpy.loadtxt加载包含浮点数和字符串的文本文件

30 投票
2 回答
118878 浏览
提问于 2025-04-18 05:51

我有一个文本文件,叫做 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

我想知道怎么用 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)

2 个回答

28

看起来把数字和文字放在一起让你遇到了很多麻烦。如果你决定把它们分开,我有个解决办法:

values = np.loadtxt('data', delimiter=',', usecols=[0,1,2,3])
labels = np.loadtxt('data', delimiter=',', usecols=[4])
49

如果你使用 np.genfromtxt,可以设置 dtype=None,这样会让 genfromtxt 智能地猜测每一列的数据类型。最方便的是,这样你就不用再为字符串列指定需要多少字节了。(如果你直接用 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')])

如果你想使用 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)

主要的区别就是把 np.str 改成 |S15(表示15字节的字符串)。

另外要注意,open("data.txt"), 'r' 应该写成 open("data.txt", 'r')。不过因为 np.loadtxt 可以直接接受文件名,所以其实你根本不需要使用 open

撰写回答