在python numpy中创建动态数组名称

时间:2017-07-08 01:24:04

标签: python arrays numpy

在SO上已经有几个类似的问题,例如How do I create a variable number of variables?。但我认为我的问题有点不同。

我想创建动态数组名称。 MATLAB(和Octave)内置了可以完成工作的数据结构单元阵列。例如,代码动态创建A {1}到A {10}个变量。 var1是动态输入'编程。

var1=10;
for j=1:1:var1
  A{j} = {}; %creating empty cell
end
%resizing empty cells using a loop, arrays can be of different size

如第一个问题所述,python有字典来完成这项任务。但是,我正在处理以数组形式存储的大量数据,并且需要使用numpy数组,因为它们比列表中的python更快。有什么建议吗?

更新: 我想在之后创建可变大小的数组。

3 个答案:

答案 0 :(得分:1)

您可以使用numpy.memmap创建这种数组。

  
    
      

data = np.arange(12,dtype ='float32')

             

data.resize((3,4))

    
  
  • numpy.memmap文档。

答案 1 :(得分:1)

所以你的Octave代码产生:

A =
{
  [1,1] =
  {
    [1,1] = [](0x0)
    [1,2] = [](0x0)
    [1,3] = [](0x0)
    [1,4] = [](0x0)
    [1,5] = [](0x0)
    [1,6] = [](0x0)
    [1,7] = [](0x0)
    [1,8] = [](0x0)
    [1,9] = [](0x0)
    [1,10] = [](0x0)
  }
  [1,2] =
  {
    [1,1] = [](0x0)
    [1,2] = [](0x0)
    [1,3] = [](0x0)
    [1,4] = [](0x0)
    [1,5] = [](0x0)
    [1,6] = [](0x0)
    [1,7] = [](0x0)
    [1,8] = [](0x0)
    [1,9] = [](0x0)
    [1,10] = [](0x0)
  }
  ...
  [1,10] =
  {
    [1,1] = [](0x0)
    [1,2] = [](0x0)
    ...
    [1,9] = [](0x0)
    [1,10] = [](0x0)
  }
}

所以A是一个包含10个单元的单元,每个单元有10个0x0矩阵。

单元格是2d(或更高)并包含任何类型的对象。 python列表是1d并包含任何类型的对象。 numpy数组更像矩阵,除了它们可以是0或1d。另一个区别是MATLAB / Octave可以通过分配更高的索引来“增长”数组和单元格。您使用.append增加列表,并且'grow'数组将多个数组连接在一起以创建一个新数组(没有就地增长)。

In [559]: A = []
In [560]: for i in range(10):
     ...:     A.append([[] for _ in range(10)])
     ...:     
In [561]: A
Out[561]: 
[[[], [], [], [], [], [], [], [], [], []],
 [[], [], [], [], [], [], [], [], [], []],
 ...
 [[], [], [], [], [], [], [], [], [], []],
 [[], [], [], [], [], [], [], [], [], []],
 [[], [], [], [], [], [], [], [], [], []]]

或者如果你想要一个(0,0)数组的列表列表:

In [562]: A =[]    
In [563]: for i in range(10):
     ...:     A.append([np.zeros((0,0)) for _ in range(10)])

或者你可以初始化一个多维数组:

In [565]: np.zeros((10,10,0,0),int)
Out[565]: array([], shape=(10, 10, 0, 0), dtype=int32)
In [566]: np.zeros((1,10,1,10,0,0),int)
Out[566]: array([], shape=(1, 10, 1, 10, 0, 0), dtype=int32)

Octave等价物:

>> zeros(1,10,1,10,0,0)
ans = [](1x10x1x10x0x0)

numpy也有对象dtype列表,其中可以包含“任何内容”。

如果我将Octave A保存到mat文件中,并将其加载到numpy中,我会得到:

In [569]: data = loadmat('test.mat')
In [570]: data
Out[570]: 
{'A': array([[ array([[array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64)]], dtype=object),
         array([[array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         ...
         array([[array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64),
         array([], shape=(0, 0), dtype=float64)]], dtype=object)]], dtype=object),
 '__globals__': [],
 '__header__': b'MATLAB 5.0 MAT-file, written by Octave 4.0.0, 2017-07-08 02:13:25 UTC',
 '__version__': '1.0'}

A是一个对象dtype数组,包含包含(0,0)浮点数组的对象dtype数组:

In [572]: data['A'].shape
Out[572]: (1, 10)
In [573]: data['A'][0,0].shape
Out[573]: (1, 10)
In [574]: data['A'][0,0][0,0].shape
Out[574]: (0, 0)

如果没有MATLAB的自动增长行为,将numpy数组初始化为形状(0,0)没有多大意义。

更简单的例子

创建不同大小的数组的简单示例 - 在列表中:

In [590]: A = [np.arange(i+3) for i in range(5)]
In [591]: A
Out[591]: 
[array([0, 1, 2]),
 array([0, 1, 2, 3]),
 array([0, 1, 2, 3, 4]),
 array([0, 1, 2, 3, 4, 5]),
 array([0, 1, 2, 3, 4, 5, 6])]

我可以保存并重新加载它:

In [600]: savemat('test.mat', {'A':A})
In [601]: loadmat('test.mat')
Out[601]: 
{'A': array([[array([[0, 1, 2]]), array([[0, 1, 2, 3]]),
         array([[0, 1, 2, 3, 4]]), array([[0, 1, 2, 3, 4, 5]]),
         array([[0, 1, 2, 3, 4, 5, 6]])]], dtype=object),
 '__globals__': [],
 '__header__': b'MATLAB 5.0 MAT-file Platform: posix, Created on: Sun Jul  9 09:44:45 2017',
 '__version__': '1.0'}

请注意,这已将数组列表转换为数组的对象数组。

Octave将其加载为:

>> A
A =
{
  [1,1] =
    0  1  2
  [1,2] =
    0  1  2  3
  [1,3] =
    0  1  2  3  4
  [1,4] =
    0  1  2  3  4  5
  [1,5] =
    0  1  2  3  4  5  6
}

答案 2 :(得分:0)

好的,据我所知,你想创建几个不同大小的数组,所以最终的数据结构不是矩形的。 Numpy-arrays必须是矩形的,所以你不能只使用它们。 你可以做的是创建一个list numpy数组。列表只是一个包含任意对象序列的数据结构,因此它不关心它的元素是否是相同大小的数组。

如果您想要将代码翻译为1:1,请执行以下操作:

import numpy as np

var1=10;
a = []
for j in range(var1):
    # you cant use a[j] in python because the j-th element does not exist yet, so use .append instead to add an element to the end
    a.append(np.array(0))
end

现在你有一个包含10个空numpy数组的列表,你可以遍历它们来调整它们的大小或添加数据等。

获得上述内容的一种更简单的方法是,它的语法不同:

import numpy as np

var1 = 10
a = [np.array(0) for i in range(var1)]

要更改,调整大小,添加数据只需循环遍历列表:

for arr in a:
    # arr is the numpy array
    arr.resize(...)