【问题标题】:NumPy: mismatch in size of old and new data-descriptorNumPy:新旧数据描述符的大小不匹配
【发布时间】:2016-03-21 13:39:52
【问题描述】:

我在读取 CSV 文件时遇到了 NumPy 1.10.2 的以下问题。我不知道如何为genfromtxt 提供显式数据类型。

这是 CSV,minimal.csv

x,y
1,hello
2,hello
3,jello
4,jelly
5,belly

这里我尝试用genfromtxt阅读:

import numpy
numpy.genfromtxt('minimal.csv', dtype=(int, str))

我也试过了:

import numpy
numpy.genfromtxt('minimal.csv', names=True, dtype=(int, str))

无论如何,我得到了错误:

Traceback (most recent call last):
  File "visualize_numpy.py", line 39, in <module>
    numpy.genfromtxt('minimal.csv', dtype=(int, str))
  File "/Users/xeli/workspace/myproj/env/lib/python3.5/site-packages/numpy/lib/npyio.py", line 1518, in genfromtxt
    replace_space=replace_space)
  File "/Users/xeli/workspace/myproj/env/lib/python3.5/site-packages/numpy/lib/_iotools.py", line 881, in easy_dtype
    ndtype = np.dtype(ndtype)
ValueError: mismatch in size of old and new data-descriptor

或者,我尝试过:

import numpy
numpy.genfromtxt('minimal.csv', dtype=[('x', int), ('y', str)])

哪个抛出:

Traceback (most recent call last):
  File "visualize_numpy.py", line 39, in <module>
    numpy.genfromtxt('minimal.csv', dtype=[('x', int), ('y', str)])
  File "/Users/xeli/workspace/myproj/env/lib/python3.5/site-packages/numpy/lib/npyio.py", line 1834, in genfromtxt
    rows = np.array(data, dtype=[('', _) for _ in dtype_flat])
ValueError: size of tuple must match number of fields.

我知道dtype=None 让 NumPy 尝试猜测正确的类型并且通常效果很好。但是,文档提到它比显式类型慢得多。在我的情况下,计算效率是必需的,所以dtype=None 不是一个选项。

我的方法或 NumPy 有什么严重问题吗?

【问题讨论】:

  • 我遇到了一个非常相似的问题,我通过将 dtype 作为列表而不是元组来解决了这个问题,您的情况似乎也是如此。

标签: python csv numpy genfromtxt


【解决方案1】:

这很好用,并保留了您的标题信息:

df = numpy.genfromtxt('minimal.csv',
                      names=True,
                      dtype=None,
                      delimiter=',')

这使genfromtxt 猜测 dtype,这通常是您想要的。分隔符是一个逗号,所以我们也应该传递那个参数,最后,names=True 保留了标题信息。

像使用任何框架一样简单地访问您的数据:

>>>>print(df['x'])
[1 2 3 4 5]

编辑:根据您在下面的评论,您可以明确提供 dtype,如下所示:

df = numpy.genfromtxt('file1.csv',
                      names=True,
                      dtype=[('x', int), ('y', 'S5')], # assuming each string is of len =< 5
                      delimiter=',')

【讨论】:

  • 谢谢!抱歉,不幸的是,dtype=None 不适合我的情况,因为它很慢。我将此添加到问题中。我只是不知道如何明确地将类型赋予 genfromtxt。
  • @AkseliPalén,查看我的更新答案!我希望这会有所帮助:)
【解决方案2】:

documentation一瞥,默认delimiter=None

试试numpy.genfromtxt('minimal.csv', dtype=(int, str), names=True, delimiter=',')

【讨论】:

  • 你可以使用names=True从第一行读取列名
  • @MaxNoe 哦,我的错。所以分隔符字段并不重要。
  • names=True 替换 skip_header。你仍然需要delimiter=','dtype=None
【解决方案3】:

我处于同样的位置,我不确定为什么我提供的类型会引发错误。也就是说,这对您来说可能是一个可行的解决方案。这是一个使用我的数据集的示例,看起来与您的相似。

首先,加载一些数据并检查 NumPy 使用的实际数据类型:

>>> movies = np.genfromtxt('movies.csv', delimiter='|', dtype=None)
>>> movies
array([(1, 'Toy Story (1995)'), (2, 'GoldenEye (1995)'),
       (3, 'Four Rooms (1995)'), ..., (1680, 'Sliding Doors (1998)'),
       (1681, 'You So Crazy (1994)'),
       (1682, 'Scream of Stone (Schrei aus Stein) (1991)')],
      dtype=[('f0', '<i8'), ('f1', 'S81')])

然后使用检测到的类型加载所有数据:

>>> movies = np.genfromtxt('movies.csv', delimiter='|', 
                           dtype=[('f0', '<i8'), ('f1', 'S81')]) 

诚然,这并不像知道 NumPy 抛出错误的原因那样令人满意,但它适用于您的特定用例。

【讨论】:

    猜你喜欢
    • 2012-10-16
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 2021-03-29
    • 1970-01-01
    • 2019-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多