具有数据类型的2D NumpyArray

时间:2016-03-03 15:01:04

标签: python arrays numpy multidimensional-array

我想创建一个python shape(2,7)的2D Numpy数组,指定每列的类型。一些列将是数组。所以我想要的数组应该是这样的:

[[ (0, [0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])]
 [(0, [0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])]]

我试过

>>> A = np.zeros(shape=(2), dtype= 'int, (3)float, (8)float, (8)float, (8)float, (10)float, (10)float')

但是我得到了一维数组:

>>> print A
[ (0, [0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
 (0, [0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])]

如果我这样定义:

>>> A = np.zeros(shape=(2,7), dtype= 'int, (3)float, (8)float, (8)float, (8)float, (10)float, (10)float')

我得到的阵列比我想要的大得多;它(2,7x7)。

执行此操作时出现错误:

>>> A = np.zeros(shape=([[2],[7]]), dtype= 'int, (3)float, (8)float, (8)float, (8)float, (10)float, (10)float')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: an integer is required

我不明白如何获得我的输出。任何帮助,可能有解释,非常感谢!谢谢!

2 个答案:

答案 0 :(得分:3)

A = np.zeros(shape=(2), dtype= '...')表示制作一个形状为(2,)且复合dtype的数组。这正是你得到的。

(2,)是一个形状。它命名了字段而不是列。指定(2,7)形状只会生成具有相同7个字段的2d数组。

如果这样dtype,您就会得到structured array。您可以按名称访问字段,例如A['f0']

如果您希望使用此方法,请阅读dtype和结构化数组上的文档。

另一个答案会引导您pandas。这对你的目的可能更好 - 或许不是。但是在幕后pandas使用numpy数组,对于像这样的混合数据,它将使用结构化数组或dtype=object

使用更简单的dtype

In [742]: A = np.zeros(shape=(2), dtype= 'int, (3)float, (4)float')
In [743]: A
Out[743]: 
array([(0, [0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]),
       (0, [0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0])], 
      dtype=[('f0', '<i4'), ('f1', '<f8', (3,)), ('f2', '<f8', (4,))])

第一个字段是1d的整数数组:

In [744]: A['f0']
Out[744]: array([0, 0])

第三个可以被视为2x4的花车

In [745]: A['f2']
Out[745]: 
array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])

您可以从此阵列中选择记录或元素:

In [746]: A[0]
Out[746]: (0, [0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0])

您可以对各个字段执行常规数值数组操作。但跨领域的经营是有限的。

你不能例如np.sum(A),跨领域相加;但你可以在一个领域采取行动:

In [749]: np.sum(A['f1'],axis=1)
Out[749]: array([ 0.,  0.])

结构化数组通常是通过读取CSV文件创建的,其中字段对应于文件中的列,而某些列是文本。

例如,我说明的A可以代表一个文件,其中第一列是记录/行计数器,接下来的3个数字代表一个值,后面的4代表逻辑上不同的值。另一种方法是制作一个(2,(1+3+4)) 2d浮点阵列。

关于设置复合类型数组的元素:

In [916]: A = np.zeros(shape=(2), dtype= 'int, (3)float, (4)float')

我可以使用匹配的大小数组或列表设置一个字段的所有值:

In [918]: A['f0']=[1,2]

我可以在同一个地方设置多元素字段的所有值;我在这里填写所有内容:

In [920]: A['f1']=1
In [921]: A
Out[921]: 
array([(1, [1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]),
       (2, [1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0])], 
      dtype=[('f0', '<i4'), ('f1', '<f8', (3,)), ('f2', '<f8', (4,))])

我可以用通常的方式对其中一个字段进行索引和切片,对其进行处理,在本例中为二维数组:

In [922]: A['f2'][1,2:]=34
In [923]: A
Out[923]: 
array([(1, [1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]),
       (2, [1.0, 1.0, 1.0], [0.0, 0.0, 34.0, 34.0])], 
      dtype=[('f0', '<i4'), ('f1', '<f8', (3,)), ('f2', '<f8', (4,))])

我无法将一个记录(行)的所有值分配给值列表,甚至是嵌套值:

In [924]: A[1]=[3,[1,2,3],[1,2,3,4]]
...
TypeError: 'list' does not support the buffer interface

但我可以用元组设置它

In [925]: A[1]=(3,[1,2,3],[1,2,3,4])
In [926]: A
Out[926]: 
array([(1, [1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]),
       (3, [1.0, 2.0, 3.0], [1.0, 2.0, 3.0, 4.0])], 
      dtype=[('f0', '<i4'), ('f1', '<f8', (3,)), ('f2', '<f8', (4,))])

在处理结构化数组时,列表和元组之间的区别很重要。请注意,在A的显示中,每个记录都显示为元组()。可以使用元组列表设置或初始化多行A。元组的使用在包含数组的维度和dtype中的结构之间绘制线。

答案 1 :(得分:1)

这可能最适合作为评论,我认为它包含足够的信息作为答案。

Numpy数组不是您想要的,您最好查看其他工具,例如Pandas Dataframe。 你需要了解一个numpy数组是什么;从numpy array的文档中,你有这样的陈述:

  

NumPy提供了一个N维数组类型,即ndarray,它描述了一组相同类型的“项目”。

这与你想要达到的目标有些相反。从相同的文档中,您有另一个声明:

  

从数组中提取的项(例如,通过索引)由Python对象表示,其类型是Numpy中构建的数组标量类型之一。阵列标量允许轻松操纵更复杂的数据排列。

这意味着您提供的数据类型必须与其中一种标量类型相对应。您提供了许多标量类型的字符串。