如何处理来自genfromtxt
的混合数据是一个经常出现的问题。人们期望得到一个二维数组,但实际上会得到一个无法按列索引的一维数组。这是因为他们得到了一个结构化数组——每个列具有不同的数据类型。
genfromtxt
文档中的所有示例都展示了这一点:
>>> s = StringIO("1,1.3,abcde")
>>> data = np.genfromtxt(s, dtype=[('myint','i8'),('myfloat','f8'),
... ('mystring','S5')], delimiter=",")
>>> data
array((1, 1.3, 'abcde'),
dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', '|S5')])
但让我演示如何访问这种数据。
In [361]: txt=b"""A, 1,2,3
...: B,4,5,6
...: """
In [362]: data=np.genfromtxt(txt.splitlines(),delimiter=',',dtype=('S1,int,float,int'))
In [363]: data
Out[363]:
array([(b'A', 1, 2.0, 3), (b'B', 4, 5.0, 6)],
dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<f8'), ('f3', '<i4')])
因此,我的数组有2条记录(检查形状),它们以列表中的元组形式显示。
您可以通过名称访问fields
,而不是通过列编号(我需要添加一个结构化数组文档链接吗?)
In [364]: data['f0']
Out[364]:
array([b'A', b'B'],
dtype='|S1')
In [365]: data['f1']
Out[365]: array([1, 4])
在这种情况下,如果我选择一个具有“子数组”的
dtype
可能更加有用。这是一个更高级的
dtype
主题。
In [367]: data=np.genfromtxt(txt.splitlines(),delimiter=',',dtype=('S1,(3)float'))
In [368]: data
Out[368]:
array([(b'A', [1.0, 2.0, 3.0]), (b'B', [4.0, 5.0, 6.0])],
dtype=[('f0', 'S1'), ('f1', '<f8', (3,))])
In [369]: data['f1']
Out[369]:
array([[ 1., 2., 3.],
[ 4., 5., 6.]])
字符列仍然被加载为S1
,但数字现在是一个包含3个列的数组。请注意,它们都是浮点数(或整数)。
In [371]: from scipy import stats
In [372]: stats.describe(data['f1'])
Out[372]: DescribeResult(nobs=2,
minmax=(array([ 1., 2., 3.]), array([ 4., 5., 6.])),
mean=array([ 2.5, 3.5, 4.5]),
variance=array([ 4.5, 4.5, 4.5]),
skewness=array([ 0., 0., 0.]),
kurtosis=array([-2., -2., -2.]))
pandas
,因为它对于这种情况更加强大。 - HoltValueError: could not convert string to float: 'F'
错误。 - betascikit-learn
结合使用,并且许多示例都基于numpy... 我认为我不需要处理非均匀数据。我只有一列是字符串,因为它是分类数据。 - betastats.describe(dataset['f2'])
,而不是stats.describe(dataset[2])
。 - Warren Weckesser