NumPy:旧数据描述符和新数据描述符的尺寸不匹配

7

当我读取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有什么严重的问题吗?


2
我曾经遇到一个非常类似的问题,我通过将dtype作为列表而不是元组来解决它,看起来对你的情况也是如此。 - pela
3个回答

3

这个方法很好用,可以保留您的标题信息:

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

这样genfromtxt会猜测dtype,通常这正是你想要的。分隔符是逗号,所以我们也应传递该参数,最后names=True保留标题信息。
只需像处理任何数据框一样访问数据即可:
>>>>print(df['x'])
[1 2 3 4 5]

编辑:根据你下面的评论,你可以明确提供数据类型,像这样:

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

谢谢!很抱歉,由于速度较慢,dtype=None在我的情况下不适用。我已将此添加到问题中。我只是无法弄清楚如何明确地给genfromtxt指定类型。 - Akseli Palén
@AkseliPalén,请看我的更新答案!希望这能帮到你 :) - Nelewout

0

从简要查看文档,默认delimiter=None

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


你可以使用 names=True 从第一行读取列名。 - MaxNoe
@MaxNoe 对不起,我的错。那么定界符字段就不重要了。 - pushkin
names=True 替代了 skip_header。你仍需要指定 delimiter=','dtype=None - hpaulj

0

我和你一样,也不确定为什么我的提供的类型会出错。不过,这可能对你是可行的解决方案。以下是一个使用类似于你的数据集的示例。

首先,加载一些数据并检查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 报错的原因,但对于您特定的使用情况是可行的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接