我正在使用genfromtxt()
读取CSV,并且我希望我的所有值都是字符串。我需要指定字符串dtype
,但指定S
结果为空字符串:
In [83]: s = StringIO("a,b,cn1,1.3,abcden2,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
,它会"自动"计算出dtypes,但我希望它们都是字符串,上面的例子将给出int/float。
我也看到了这个:https://stackoverflow.com/a/14639568/1406873建议使用python object
dtype,但这似乎为我的需求增加了太多的开销。
我想我可以先阅读整个CSV,跟踪最大列长度,然后用这些长度调用genfromtxt()。还有其他想法吗?
引用:
- https://docs.scipy.org/doc/numpy/reference/generated/numpy.genfromtxt.html
- https://docs.scipy.org/doc/numpy/user/basics.io.genfromtxt.html
- https://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html
genfromtxt
一般地对待str
(或np.str
) -至少在Py3
In [590]: np.genfromtxt(b"a,b,cn1,1.3,abcden2,4,hihihi".splitlines(), dtype=str)
Out[590]:
array(['a,b,c', '1,1.3,abcde', '2,4,hihihi'],
dtype='<U11')
In [591]: np.genfromtxt(b"a,b,cn1,1.3,abcden2,4,hihihi".splitlines(),dtype=str, delimiter=',')
Out[591]:
array([['a', 'b', 'c'],
['1', '1.3', 'abcde'],
['2', '4', 'hihihi']],
dtype='<U6')