将matplotlib的路径插入Numpy ndarray

时间:2016-10-21 14:44:51

标签: python numpy matplotlib

我需要将一个matplotlib Path对象插入到一个numpy数组中,应该使用什么dtype?

这就是我所拥有的:

import numpy as np

dtypes = np.dtype([('Shape', '<f8', (2,)), ('FIELD2', '<U254'), ('FIELD3', '<U254'),
                   ('FIELD4', '<U254'), ('FIELD5', '<i4'),
                   ('Length', '<f8'), ('OID@', '<i4')])

b = np.array([([ 93.59900552,  22.62355019], u'randomtext', u'atext', 9999, 1, 1.2119301339479824, 1),
 ([ 93.59901266,  22.6233646 ], u'randomtext', u'atext', 9999, 1, 1.2119301339479824, 1),
 ([ 93.59901623,  22.62300054], u'randomtext', u'atext', 9999, 1, 1.2119301339479824, 1),
 ([ 93.59913044,  22.62273999], u'randomtext', u'atext', 9999, 1, 1.2119301339479824, 1),
 ([ 93.59924109,  22.62261507], u'randomtext', u'atext', 9999, 1, 1.2119301339479824, 1),
 ([ 93.59925536,  22.62240805], u'randomtext', u'atext', 9999, 1, 1.2119301339479824, 1),
 ([ 93.59936601,  22.62212966], u'randomtext', u'atext', 9999, 1, 1.2119301339479824, 1),
 ([ 93.59954804,  22.6220083 ], u'randomtext', u'atext', 9999, 1, 1.2119301339479824, 1),
 ([ 93.59976219,  22.62173348], u'randomtext', u'atext', 9999, 1, 1.2119301339479824, 1),
 ([ 93.60013339,  22.62131588], u'randomtext', u'atext', 9999, 1, 1.2119301339479824, 1)],
             dtype=dtypes)

我想将点转换为matplotlib路径对象,但是当我将dtypes设置为:

dtypes = np.dtype([('Shape', object), ('FIELD2', '<U254'), ('FIELD3', '<U254'),
                   ('FIELD4', '<U254'), ('FIELD5', '<i4'),
                   ('Length', '<f8'), ('OID@', '<i4')])

然后转换matplotlib.path.Path()执行以下操作:

new_array = np.array([], dtypes)
for id in set(b['OID@'].tolist()):
    sub_array = array[np.where(array['OID@'] == oid)]
    geom = matplotlib.path.Path(sub_array['Shape'])
    row = list(sub_array[0])
    row[0] = geom
    new_array = np.array([row], dtypes)
    new_arrray = numpy.vstack([sub_array, new_array]) 

谢谢

2 个答案:

答案 0 :(得分:1)

在对你的编辑进行疑惑和实验之后,我认为这是怎么回事:

使用dtypes我可以制作一个'空'数组

In [995]: dtypes
Out[995]: dtype([('Shape', 'O'), ('FIELD2', '<U254'), ('FIELD3', '<U254'), ('FIELD4', '<U254'), ('FIELD5', '<i4'), ('Length', '<f8'), ('OID@', '<i4')])
In [996]: x=np.empty((3,),dtypes)
In [997]: x
Out[997]: 
array([(None, '', '', '', 0, 0.0, 0), (None, '', '', '', 0, 0.0, 0),
       (None, '', '', '', 0, 0.0, 0)], 
      dtype=[('Shape', 'O'), ('FIELD2', '<U254'), ('FIELD3', '<U254'), ('FIELD4', '<U254'), ('FIELD5', '<i4'), ('Length', '<f8'), ('OID@', '<i4')])

np.array([],dtypes)np.empty((0,),dtypes)相同;这个dtype的零元素数组。这只适用于重复stacking

我可以使用

创建一个Path对象
In [1000]: apath=matplotlib.path.Path(np.arange(4).reshape(2,2))

Shape字段有dtype=object;所以我可以为它分配任何对象

In [1001]: x['Shape']
Out[1001]: array([None, None, None], dtype=object)

In [1002]: x['Shape'][0]=apath
In [1003]: x['Shape'][1]=matplotlib.path.Path(np.arange(6).reshape(3,2))
In [1004]: x
Out[1004]: 
array([ (Path(array([[ 0.,  1.],
       [ 2.,  3.]]), None), '', '', '', 0, 0.0, 0),
       (Path(array([[ 0.,  1.],
       [ 2.,  3.],
       [ 4.,  5.]]), None), '', '', '', 0, 0.0, 0),
       (None, '', '', '', 0, 0.0, 0)], 
      dtype=[('Shape', 'O'), ('FIELD2', '<U254'), ('FIELD3', '<U254'), ('FIELD4', '<U254'), ('FIELD5', '<i4'), ('Length', '<f8'), ('OID@', '<i4')])

或者对于单个元素数组:

In [1010]: y=np.empty((1,),dtypes)
In [1011]: y['Shape']=apath

也许这比你正在尝试的更接近:

使用dtypes数组的元素作为“模板”:

In [1012]: x[2]
Out[1012]: (None, '', '', '', 0, 0.0, 0)
In [1013]: row=x[2]
In [1014]: row[0]=apath     # assign `apath` to a slot
In [1015]: row
Out[1015]: 
(Path(array([[ 0.,  1.],
       [ 2.,  3.]]), None), '', '', '', 0, 0.0, 0)

row是一个np.void对象,而不是列表或元组

我可以制作一个包含这个对象的数组:

In [1016]: np.array(row,dtypes)
Out[1016]: 
array((Path(array([[ 0.,  1.],
       [ 2.,  3.]]), None), '', '', '', 0, 0.0, 0), 
      dtype=[('Shape', 'O'), ('FIELD2', '<U254'), ('FIELD3', '<U254'), ('FIELD4', '<U254'), ('FIELD5', '<i4'), ('Length', '<f8'), ('OID@', '<i4')])

[row]不起作用

In [1017]: np.array([row],dtypes)
...
ValueError: Setting void-array with object members using buffer.

np.void转换为元组确实有效。通常,结构化数组是创建或填充元组列表(或逐字段)。

In [1018]: np.array([tuple(row)],dtypes)
Out[1018]: 
array([ (Path(array([[ 0.,  1.],
       [ 2.,  3.]]), None), '', '', '', 0, 0.0, 0)], 
      dtype=[('Shape', 'O'), ('FIELD2', '<U254'), ('FIELD3', '<U254'), ('FIELD4', '<U254'), ('FIELD5', '<i4'), ('Length', '<f8'), ('OID@', '<i4')])

rowtuple(row)显示相同,但​​显然为此目的不一样。

因此,如果我读得正确,这实际上不是Path对象问题;甚至没有dtype=object问题。这是关于创建结构化数组。

答案 1 :(得分:0)

如果你想要一个python对象的numpy数组,你可以使用

np.empty(shapeInformation, dtype = object)

然后用你喜欢的任何pythonobject填充数组