try*_*ink 7 python numpy python-3.x
我有一个具有混合数据类型(即浮点数、整数和字符串)的 numpy 结构化数组。我想选择数组的一些列(所有列仅包含浮点数),然后按列获取行的总和,作为标准 numpy 数组。初始数组的形式类似于:
\n\nsome_data = np.array([(\'foo\', 3.5, 2.15), (\'bar\', 2.8, 5.3), (\'baz\', 1.2, 3.7)], \n dtype=[(\'col1\', \'<U20\'), (\'A\', \'<f8\'), (\'B\', \'<f8\')])\nRun Code Online (Sandbox Code Playgroud)\n\n对于这个例子,我想对 A 列和 B 列求和,得到np.array([7.5, 11.15])。使用 numpy \xe2\x89\xa41.13,我可以这样做:
get_cols = [\'A\', \'B\']\ndesired_sum = np.sum(some_data[get_cols].view((\'<f8\', len(get_cols))), axis=0)\nRun Code Online (Sandbox Code Playgroud)\n\n随着 numpy 1.14 的发布,此方法现在失败并显示,这是numpy 1.14 对结构化数组的处理ValueError: Changing the dtype to a subarray type is only supported if the total itemsize is unchanged进行更改的结果。(用户 bbengfort对此答案中有关此更改的 FutureWarning 发表了评论。)
鉴于结构化数组的这些变化,如何从结构化数组子集中获得所需的总和?
\nIn [165]: some_data = np.array([('foo', 3.5, 2.15), ('bar', 2.8, 5.3), ('baz', 1.2, 3.7)], dtype=[('col1', '<U20'), ('A', '<f8'), ('B', '<f8')])
...:
In [166]: get_cols = ['A','B']
In [167]: some_data[get_cols]
Out[167]:
array([( 3.5, 2.15), ( 2.8, 5.3 ), ( 1.2, 3.7 )],
dtype=[('A', '<f8'), ('B', '<f8')])
Run Code Online (Sandbox Code Playgroud)
只需读取字段值就可以了。在 1.13 中我们收到警告
In [168]: some_data[get_cols].view(('<f8', len(get_cols)))
/usr/local/bin/ipython3:1: FutureWarning: Numpy has detected that you may be viewing or writing to an array returned by selecting multiple fields in a structured array.
This code may break in numpy 1.13 because this will return a view instead of a copy -- see release notes for details.
#!/usr/bin/python3
Out[168]:
array([[ 3.5 , 2.15],
[ 2.8 , 5.3 ],
[ 1.2 , 3.7 ]])
Run Code Online (Sandbox Code Playgroud)
使用推荐的副本,没有警告:
In [169]: some_data[get_cols].copy().view(('<f8', len(get_cols)))
Out[169]:
array([[ 3.5 , 2.15],
[ 2.8 , 5.3 ],
[ 1.2 , 3.7 ]])
In [171]: np.sum(_, axis=0)
Out[171]: array([ 7.5 , 11.15])
Run Code Online (Sandbox Code Playgroud)
在你的原始数组中,
dtype([('col1', '<U20'), ('A', '<f8'), ('B', '<f8')])
Run Code Online (Sandbox Code Playgroud)
一个A,B切片将两个f8项目散布在 20U 的项目中。改变view这种混合的数据类型是有问题的。这就是为什么使用副本更可靠。
由于U20占用 4*20 字节,因此总数itemsize为 96,是 8 的倍数。我们可以将整个内容转换为f8,重塑并“丢弃”U20列:
In [183]: some_data.view('f8').reshape(3,-1)[:,-2:]
Out[183]:
array([[ 3.5 , 2.15],
[ 2.8 , 5.3 ],
[ 1.2 , 3.7 ]])
Run Code Online (Sandbox Code Playgroud)
它不是很漂亮,我不推荐它,但它可以让您深入了解结构化数据的排列方式。
view结构化数组有时很有用,但正确使用通常有点棘手。
如果这两个数字字段通常一起使用,我建议使用复合数据类型,例如:
In [184]: some_data = np.array([('foo', [3.5, 2.15]), ('bar', [2.8, 5.3]), ('baz
...: ', [1.2, 3.7])],
...: dtype=[('col1', '<U20'), ('AB', '<f8',(2,))])
...:
...:
In [185]: some_data
Out[185]:
array([('foo', [ 3.5 , 2.15]), ('bar', [ 2.8 , 5.3 ]),
('baz', [ 1.2 , 3.7 ])],
dtype=[('col1', '<U20'), ('AB', '<f8', (2,))])
In [186]: some_data['AB']
Out[186]:
array([[ 3.5 , 2.15],
[ 2.8 , 5.3 ],
[ 1.2 , 3.7 ]])
Run Code Online (Sandbox Code Playgroud)
genfromtxt接受这种风格dtype。
| 归档时间: |
|
| 查看次数: |
2099 次 |
| 最近记录: |