用命名元组初始化numpy数组
我正在尝试初始化一个包含命名元组的NumPy数组。当我用empty
方法初始化数组并在之后设置数据时,一切都很顺利;但是当我使用numpy.array
构造函数时,NumPy的表现却和我预期的不一样。
以下是我运行的代码:
import numpy
data = numpy.random.rand(10, 3)
print data[0]
# Works
a = numpy.empty(
len(data),
dtype=numpy.dtype([('nodes', (float, 3))])
)
a['nodes'] = data
print
print a[0]['nodes']
# Doesn't work
b = numpy.array(
data,
dtype=numpy.dtype([('nodes', (float, 3))])
)
print
print b[0]['nodes']
输出结果是:
[ 0.28711363 0.89643579 0.82386232]
[ 0.28711363 0.89643579 0.82386232]
[[ 0.28711363 0.28711363 0.28711363]
[ 0.89643579 0.89643579 0.89643579]
[ 0.82386232 0.82386232 0.82386232]]
这是在使用NumPy 1.8.1版本时的情况。
有没有什么建议可以帮助我更好地使用array
构造函数呢?
2 个回答
-1
构造一个不同的数组是很有启发性的:
dt3=np.dtype([('x','<f8'),('y','<f8'),('z','<f8')])
b=np.zeros((10,),dtype=dt3)
b[:]=[tuple(x) for x in data]
b['x'] = data[:,0] # alt
np.array([tuple(x) for x in data],dtype=dt3) # or in one statement
a[:1]
# array([([0.32726803375966484, 0.5845638956708634, 0.894278688117277],)], dtype=[('nodes', '<f8', (3,))])
b[:1]
# array([(0.32726803375966484, 0.5845638956708634, 0.894278688117277)], dtype=[('x', '<f8'), ('y', '<f8'), ('z', '<f8')])
我觉得要把 data
赋值给 b
的所有字段,肯定得用某种循环。
genfromtxt
是生成这种记录数组的常用方法。看它的代码,我发现了一个模式:
data = list(zip(*[...]))
output = np.array(data, dtype)
这让我想尝试一下:
dtype=numpy.dtype([('nodes', (float, 3))])
a = np.array(zip(data), dtype=dtype)
(速度基本和 eickenberg 的理解差不多;所以它在做的也是一样的纯 Python 列表操作。)
对于这三个字段:
np.array(zip(*data.T), dtype=dt3)
有趣的是,先显式转换为列表的速度甚至更快(几乎是 zip(data)
计算的两倍)
np.array(zip(*data.T.tolist()), dtype=dt3)
0
这真让人头疼,不过:
从你复制粘贴的例子开始,放到ipython里试试
dtype=numpy.dtype([('nodes', (float, 3))])
c = numpy.array([(aa,) for aa in data], dtype=dtype)
这样似乎就能解决问题了。