【问题标题】:Loading text file containing both float and string using numpy.loadtxt使用 numpy.loadtxt 加载包含浮点数和字符串的文本文件
【发布时间】:2014-06-26 02:46:28
【问题描述】:

我有一个文本文件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)

【问题讨论】:

    标签: python python-2.7 python-3.x numpy


    【解决方案1】:

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

    如果您确实想使用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

    【讨论】:

    • 当我尝试这个时,我的字符串被读取为字节文字,例如 b'ADT1_YEAST'。我必须手动转换它们还是有办法让它像你的例子一样读取字符串?
    • @mattgabor:如果您将dtype=None 更改为dtype=['&lt;f8','&lt;f8','&lt;f8','&lt;f8','U15'],那么np.genfromtxt 会将最后一列加载为strs 而不是bytes。
    • 对我来说,当文本文件包含“#”时,loadtxt() 不起作用。由于某种原因,它返回了错误的列数。我已将 '#' 替换为其他字符,然后使用 line.replace('#',' ')
    • @vlad: genfromtxtloadtxt 有一个 comments 参数,默认设置为 '#'。注释字符之后的所有字符都被丢弃。这可能就是解析器找到错误列数的原因。您可以通过将comments 设置为'#' 以外的其他值来避免该问题。
    【解决方案2】:

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

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

    【讨论】:

    • 对于标签,我认为您需要添加dtype=np.str 才能使其正常工作。否则,你会得到ValueError: could not convert string to float: Iris-setosa 或类似的东西。
    • np.genfromtxt 总体上更健壮,自从我最初回答这个问题以来,它为我节省了很多心痛
    • 并考虑研究熊猫。你再也不会使用 .loadtxt 或 .genfromtxt 了!
    猜你喜欢
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 2021-09-12
    • 1970-01-01
    • 2018-10-07
    • 1970-01-01
    相关资源
    最近更新 更多