Python 如何向numpy数组添加名称而不更改其维度?

Python 如何向numpy数组添加名称而不更改其维度?,python,arrays,numpy,Python,Arrays,Numpy,我有一个现有的两列numpy数组,需要向其中添加列名。通过dtype传递这些信息在下面块1所示的玩具示例中起作用。但是,对于我的实际阵列,如图2所示,同样的方法会产生一个意想不到的副作用(对我来说!),即更改阵列维度 如何将实际数组(下面第二个块中名为Y的数组)转换为具有命名列的数组,就像我在第一个块中对数组A所做的那样 块1:(A的列命名时未重新调整尺寸) 尝试重新编写X的定义: X = np.array(zip(ID, RING)) 然后,您不需要定义Y=X.t您完全确定A和Y的输出吗?我

我有一个现有的两列numpy数组,需要向其中添加列名。通过
dtype
传递这些信息在下面块1所示的玩具示例中起作用。但是,对于我的实际阵列,如图2所示,同样的方法会产生一个意想不到的副作用(对我来说!),即更改阵列维度

如何将实际数组(下面第二个块中名为
Y
的数组)转换为具有命名列的数组,就像我在第一个块中对数组
A
所做的那样

块1:
A
的列命名时未重新调整尺寸)


尝试重新编写X的定义:

X = np.array(zip(ID, RING))

然后,您不需要定义Y=X.t

您完全确定
A
Y
的输出吗?我使用Python2.7.6和Numpy1.8.1得到了一些不同的东西

我的
A
的初始输出与您的相同。在为第一个示例运行以下代码之后

dt = {'names':['ID', 'Ring'], 'formats':[np.int32, np.int32]}
A.dtype=dt
数组
A
的内容实际上是

array([[(1, 0), (3, 0)],
   [(2, 0), (2, 0)],
   [(3, 0), (2, 0)],
   [(4, 0), (1, 0)],
   [(5, 0), (1, 0)],
   [(6, 0), (1, 0)]], 
  dtype=[('ID', '<i4'), ('Ring', '<i4')])
使用这段短代码,数组
B
变为

array([(1, 2), (3, 4), (50, 100)], 
  dtype=[('ID', '<i4'), ('Ring', '<i4')])
对于第二个示例,要使Y成为结构化数组,需要做类似的事情:

Y = np.array(list(map(tuple, X.T)), dtype=dt)
在对第二个示例执行此操作之后,数组Y如下所示

array([(1, 3), (2, 2), (3, 2), (4, 1), (5, 1), (6, 1)], 
  dtype=[('ID', '<i4'), ('Ring', '<i4')])
数组([(1,3)、(2,2)、(3,2)、(4,1)、(5,1)、(6,1)],

dtype=[('ID','首先,因为你的问题是关于给数组命名,我觉得有义务指出使用“结构化数组”出于命名的目的,命名可能不是最好的方法。在处理表时,我们通常喜欢给行/列命名,如果是这种情况,我建议您尝试类似的方法。如果您只是想在代码中组织一些数据,数组字典通常比结构化数组好得多,因此对于您可以做到:

Y = {'ID':X[0], 'Ring':X[1]}
因此,如果您想使用结构化数组,我认为以下是最清晰的方法:

import numpy as np

nRings = 3
nn = [[nRings+1-n] * n for n in range(nRings+1)]
RING = reduce(lambda x, y: x+y, nn)
ID = range(1,len(RING)+1)
X = np.array([ID, RING])

dt = {'names':['ID', 'Ring'], 'formats':[np.int, np.int]}
Y = np.zeros(len(RING), dtype=dt)
Y['ID'] = X[0]
Y['Ring'] = X[1]

这是因为Y不是C_连续的,您可以通过
Y.flags
检查它:

  C_CONTIGUOUS : False
  F_CONTIGUOUS : True
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
您可以先调用
Y.copy()
Y.ravel()

dt = {'names':['ID', 'Ring'], 'formats':[np.int32, np.int32]}
print Y.ravel().view(dt) # the result shape is (6, )
print Y.copy().view(dt)  # the result shape is (6, 1)
另一个页面包含一个很好的解决方案,可以将名称添加到可以用作列的数组中 例如:


是的,我对这个输出很确定。我刚刚通过在一个新的Python会话中重新运行(Windows 7 64位笔记本电脑上的2.7.6 | Anaconda 1.9.2(32位)和numpy 1.8.0)来确认了这一点。谢谢你剩下的回答,作为一个Python新手,我需要一段时间来消化。不过有两个问题。(1)对于
B
,看起来我想做
B.resforme(len(B),1)
来获得一个两列数组,对吗?(2)我如何以脚本的方式“为我的第二个示例做[]类似的事情”(因为真正的数组将有1000多个元素,我将无法像您在最后的代码块中那样写出数组)@JoshO'Brien,这是关键,32位。您使用的块A只起作用,因为您使用的是32位版本的python/numpy。一般来说,更改数组的数据类型可能是个坏主意,正如我们在这里看到的,在不同的系统上会产生不同的结果。@BiRico谢谢。尽管
A.dtype
(从手动分配到数组之前)返回
dtype('int32')
?那么,我应该如何为数组分配名称而不为
格式指定一些值,或者应该为其分配一些不同的格式?(FTR,我肯定是我遗漏了一些东西,但我确实怀疑位和格式是关键,这就是为什么我首先检查
A.dtype
…)的值的原因)@JoshO'Brien关于将
B
转换为2D数组的方法你是对的。为了回答你的第二个问题,我更新了我的答案。这看起来很奇怪。运行
Z=np.array(zip(ID,RING))
然后运行
numpy.array_equiv(Y,Z)
(带
Y=X.T
)产生
'True'
。因此
Y
Z
看起来相同(并显示
dtype
的等效值)但是当我做了
Z.dtype=dt
,我得到了我想要的数组,而
Y.dtype=dt
仍然给了我我没有的数组。你知道为什么吗?太好了。特别是作为一个R用户,熊猫看起来很棒,但我无法将其用于此应用程序。(我需要Python代码在arcpy脚本中执行一些操作,作为ArcGIS工具箱分发给用户,这些用户只能使用ArcGIS安装程序提供给他们的Python安装。它包括numpy,但不包括pandas,这就是为什么我的背后绑着一只手(至少!))因此,特别感谢您提供了一个纯numpy解决方案。一旦有机会,我将检查它如何与我的其余代码配合。FWIW,上面的“代码示例”显示了我为什么特别需要numpy“结构化数组”。是否还需要中间创建
X=np.array([ID,RING])
?看起来像是在做
Y['ID']=ID
Y['ID']=X[0]具有相同的效果
,对吗?@JoshO'Brien,你说得对。我只是假设你的数据是从一个数组开始的,比如
X
,但是如果你把它作为
ID
RING
,就没有必要创建
X
@BiRico,我意识到这是一个老问题,但是你为什么要避免使用numpy结构化数组来引用co呢用一个特定的名字命名lumns?很吸引人。我不能说我完全理解为什么它会有不同,但我现在明白了。另外,记录在案,它看起来像
np.requires(Y,requirements=['C'])
做+/-与
Y.copy()相同的事情
,在不改变数组维数的情况下转换为C_连续存储。我的想法正确吗?这可能是我了解F_连续转置数组
Y
在通过t
Y = {'ID':X[0], 'Ring':X[1]}
import numpy as np

nRings = 3
nn = [[nRings+1-n] * n for n in range(nRings+1)]
RING = reduce(lambda x, y: x+y, nn)
ID = range(1,len(RING)+1)
X = np.array([ID, RING])

dt = {'names':['ID', 'Ring'], 'formats':[np.int, np.int]}
Y = np.zeros(len(RING), dtype=dt)
Y['ID'] = X[0]
Y['Ring'] = X[1]
  C_CONTIGUOUS : False
  F_CONTIGUOUS : True
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
dt = {'names':['ID', 'Ring'], 'formats':[np.int32, np.int32]}
print Y.ravel().view(dt) # the result shape is (6, )
print Y.copy().view(dt)  # the result shape is (6, 1)
r = np.core.records.fromarrays([x1,x2,x3],names='a,b,c')
# x1, x2, x3 are flatten array
# a,b,c are field name