【发布时间】:2017-03-21 05:27:56
【问题描述】:
我正在使用 genfromtxt() 读取 CSV,并且我希望我的所有值都是字符串。我需要指定一个字符串 dtype 但指定 S 会导致空字符串:
In [83]: s = StringIO("a,b,c\n1,1.3,abcde\n2,4,hihihi")
In [84]: data = np.genfromtxt(s, dtype='S', delimiter=',', names=True)
In [85]: data
Out[85]:
array([('', '', ''), ('', '', '')],
dtype={'names':['a','b','c'], 'formats':['S','S','S'], 'offsets':[0,0,0], 'itemsize':3})
In [86]: data['a']
Out[86]:
array(['', ''],
dtype='|S1')
我认为这是因为数组不能有可变长度的列,你需要指定类似|S10:
In [98]: data = np.genfromtxt(s, dtype=[(col, '|S10') for col in ('a', 'b', 'c')], delimiter=',', skip_header=1)
In [99]: data
Out[99]:
array([('1', '1.3', 'abcde'), ('2', '4', 'hihihi')],
dtype=[('a', 'S10'), ('b', 'S10'), ('c', 'S10')])
In [100]: data['a']
Out[100]:
array(['1', '2'],
dtype='|S10')
但是如果我不知道每列的最大字符串长度怎么办?
我知道我可以指定dtype=None,它会“自动”找出数据类型,但我希望它们都是字符串,上面的示例将给出整数/浮点数。
我也看到了这个:https://stackoverflow.com/a/14639568/1406873,它建议使用 python object dtype,但这似乎对我的需求增加了太多开销。
我想我可以先通读整个 CSV,跟踪最大列长度,然后使用这些长度调用 genfromtxt()。还有其他想法吗?
参考资料:
【问题讨论】:
-
你试过
dtype=str吗? -
@hpaulj 我确实做到了。同
dtype='S' -
"using python object dtype" 你基本上得到了一个引用数组。元素访问有点慢。 “跟踪最大列长度,然后使用这些长度调用 genfromtxt()” 这也是我会做的,但请记住,您的所有字符串都将被分配最大的大小一。这也不是绝对的内存效率。
标签: python csv numpy scipy genfromtxt