【问题标题】:Converters behavior in NumPy loadtxt not understood不理解 NumPy loadtxt 中的转换器行为
【发布时间】:2011-06-20 19:55:36
【问题描述】:

我正在尝试使用带有 converters 参数的 numpy.loadtxt 从文本文件中读取数据。我混合了整数列和字符串。代码是:

a, b, c, d, e = np.loadtxt(infile, delimiter = ',', usecols=(0, 2, 5, 8, 9), skiprows = 1,
                           unpack = True, converters = dict(zip((0, 2, 5, 8, 9), (int, float, float, int, int))))

数据被正确读入并正确解包,但所有变量(a、b、c、d 和 e)最终都是浮点数。我在转换器语法中犯了错误吗?

编辑尝试回答

我尝试按照@joris 的建议使用 dtype = (int,float,float,int,int):

a,b,c,d,e = np.loadtxt(infile,delimiter = ',', usecols=(0,2,5,8,9), skiprows = 1, unpack = True, dtype = (int,float,float,int,int))

但我收到以下错误:

     41                                            skiprows = 1,
     42                                            unpack = True,
---> 43                                            dtype = (int,float,float,int,int))
     44
     45

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/lib/npyio.pyc in loadtxt(fname, dtype, comments, delimiter, converters, skiprows, usecols, unpack)
    665     try:
    666         # Make sure we're dealing with a proper dtype

--> 667         dtype = np.dtype(dtype)
    668         defconv = _getconv(dtype)
    669

TypeError: data type not understood
WARNING: Failure executing file: <forward_NDMMF.py>

我正在使用 NumPy v. 1.5.1。

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    要指定不同列的类型,可以使用参数dtype 而不是converters

    dtype=(int,float,float,int,int)
    

    编辑:

    显然,这种类型的dtype 规范似乎不适用于loadtxt,但它适用于genfromtxt有人知道为什么这不适用于loadtxt,或者这是genfromtxt的额外功能之一?

    如果您想使用loadtxt,可以使用带有元组的结构化 dtype 规范,例如 [('f0', int), ('f1', float)] 而不是 (int, float)

    但是还有另一个问题。当使用这样的结构化数据类型和结构化数组(不同列的不同类型)时,unpack 似乎不起作用。至少我尝试了一个简单的例子。但这可能是一个已经解决的错误:http://projects.scipy.org/numpy/ticket/1458(但为此,您甚至必须升级到 1.6)。

    【讨论】:

    • @joris,似乎dtype 不会接受这样的简单元组类型。您需要记录dtype
    • @senderle,奇怪,我没测试过,直接从numpy用户手册复制过来的,所以我认为是正确的
    • @senderle:举个简单的例子,它可以使用普通的元组(numpy 1.5.1)
    • @mishaF,也许可以试试genfromtxt 而不是loadtxt(使用相同的参数)。我用genfromtxt 的一个简单示例进行了尝试,然后dtype 起作用了(只有解包会出现问题)。
    • @joris。感谢更新。解包行为很重要,因为没有它我可以在读取后解析数组时进行类型转换。我会试试 genfromtxt。
    【解决方案2】:

    loadtxt 文档表明 converters 应该包含 specifically return floats:

    的函数

    转换器:字典,可选

    将列号映射到一个函数的字典,该函数将该列转换为浮点数。例如,如果第 0 列是日期字符串:converters = {0: datestr2num}。转换器也可用于为缺失数据提供默认值:转换器 = {3: lambda s: float(s or 0)}。默认值:无。

    如果您想要整数,则需要使用 dtype 关键字转换浮点数。

    >>> numpy.loadtxt('th.txt', delimiter=',', usecols=(0, 2, 3), converters=dict(zip((0, 2, 3), (float, float, float))), dtype=([('i1', '<i4'), ('i2', '<f4'), ('i3', '<i4')]))
    array([(1, 3.2000000476837158, 4), (1, 3.2000000476837158, 4),
           (1, 3.2000000476837158, 4), (1, 3.2000000476837158, 4),
           (1, 3.2000000476837158, 4), (1, 3.2000000476837158, 4),
           (1, 3.2000000476837158, 4), (1, 3.2000000476837158, 4),
           (1, 3.2000000476837158, 4)],
          dtype=[('i1', '<i4'), ('f1', '<f4'), ('i2', '<i4')])
    

    当然,在这种情况下,您实际上并不需要converters——这实际上是用于将任意字符串值(如'True')转换为数值。此外,如果您实际上想要一个简单的二维数组而不是记录数组,则不要传递记录格式:

    >>> numpy.loadtxt('th.txt', delimiter=',', usecols=(0, 2, 3), dtype=int)
    array([[1, 3, 4],
           [1, 3, 4],
           [1, 3, 4],
           [1, 3, 4],
           [1, 3, 4],
           [1, 3, 4],
           [1, 3, 4],
           [1, 3, 4],
           [1, 3, 4]])
    

    但如果你这样做,你就不能按列指定格式。

    【讨论】:

    • 实际上,只传递一个类型的元组 (joris's answer) 适用于 numpy 1.5.1。
    • 我应该更仔细地阅读文档!不过,按列指定格式是我的最终目标。
    猜你喜欢
    • 1970-01-01
    • 2015-09-29
    • 2014-01-26
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    • 2023-03-19
    相关资源
    最近更新 更多