将对象分配给多个变量 - python

时间:2013-11-21 19:49:30

标签: python variables numpy

是否可以一次性将一个numpy对象分配给多个变量?

例如,我想用np.zeros((2,), dtype=np.object)

启动许多变量

我想过做a,b,c = np.zeros((2,), dtype=np.object)但得到ValueErrora=b=c=np.zeros((2,), dtype=np.object)也不起作用,因为如果我更改了一个变量,其他变量也会发生变化。

有三个变量,如上面的例子,手动操作不是问题,但是当我有几十个时,能够以更有效的方式做到这一点会很方便。

编辑 - 一个更具体的例子是:

a = np.zeros((2,),dtype=np.object)
b = np.zeros((2,),dtype=np.object)
c = np.zeros((2,),dtype=np.object)


a[0] = pd.Series(data=np.random.rand(10))
a[1] = pd.Series(data=np.random.rand(5))

b[0] = 'text1'
b[1] = 'text2'

c[0] = [0,0,0,0,0,0,0,0,0]
c[1] = [1,1,1,1,1]

data = {'a':a, 'b':b, 'c':c}

sio.savemat('test.mat',{'data':data})

4 个答案:

答案 0 :(得分:5)

使用列表理解:

>>> a, b, c = [np.zeros((2,), dtype=np.object) for _ in xrange(3)]
>>> [id(x) for x in (a,b,c)]      
[172542064, 171775688, 168893512] #Different objects

如果您计划添加许多此类变量,then better use a dictionary

>>> my_vars = {x:np.zeros((2,), dtype=np.object) for x in 'abcdef'}
>>> my_vars
{'a': array([0, 0], dtype=object), 'c': array([0, 0], dtype=object), 'b': array([0, 0], dtype=object), 'e': array([0, 0], dtype=object), 'd': array([0, 0], dtype=object), 'f': array([0, 0], dtype=object)}

答案 1 :(得分:1)

在您的实际代码中,没有理由让这些变量只是因为您可以将它们全部插入到dict中。并且也没有理由首先将值初始化为相等的数组,这样您就可以将它们变异为您真正想要的数组。如果你以明显的方式写下所有内容,那么你试图解决的问题甚至都不会出现:

data = {}
data['a'] = np.array([pd.Series(data=np.random.rand(10)),
                      pd.Series(data=np.random.rand(5))])
data['b'] = np.array(['text1', 'text2'])
data['c'] = np.array([[0,0,0,0,0,0,0,0,0], [1,1,1,1,1]])
sio.savemat('test.mat',{'data':data})

如果你认为你需要预先创建然后改变数组,以保证你得到你想要的结果,正如你在评论中所声称的那样......首先,只需运行此代码,你就会看到你得到的结果三个1D对象数组,而不是其他东西的2D数组。但是如果您不知道如何为自己确定,并且不想只是尝试并进行测试,则可以始终明确指定dtype(作为object,或作为复杂()强迫它。

同时,即使你需要预先创建数组(再次,你没有),仍然没有理由创建几十个单独的变量然后把事后,他们在一个字典中。换句话说,就这样做:

arrays = np.zeros((3,2), dtype=np.object)
data = dict(zip(string.ascii_lowercase, arrays))

或者,如果您因某种原因确实需要完全独立的数组,而不是从更高维数组中切出:

arrays = [np.zeros((2,), dtype=np.object) for _ in range(3)]
data = dict(zip(string.ascii_lowercase, arrays))

当然,如果你多次这样做,你可以把它全部包含在一个函数中。

答案 2 :(得分:1)

制作多个数组的好方法是将所需输出数组的数量添加为第一个维度(axis 0)。所以,如果你想要三个长度为2的数组,用dtype对象的零填充,你可以这样做:

a, b, c = np.zeros((3,2), object)

这适用于任何数组,其中解包来自第一个轴,例如:

a, b, c = np.random.rand(3, 4, 5)
a, b  = np.arange(12).reshape(2,-1)

N.B。:这与做

不同
a, b, c = [np.zeros((2,), object) for _ in xrange(3)]

因为在这种情况下,每个数组都是单独创建的,并且在内存中不一定是连续的。如果使用单个数组的解包,则首先将原始数组创建为一个连续的数组,新数组只是原始数组的视图。你还没有保存原始数组,所以我看不到任何效果,但如果你确实存储了,那么拆分数组,你就会看到它们共享数据:

In [96]: orig = np.zeros((3,2), dtype=np.object)

In [97]: a, b, c = orig

In [98]: orig
Out[98]: 
array([[0, 0],
       [0, 0],
       [0, 0]], dtype=object)

In [99]: a
Out[99]: array([0, 0], dtype=object)

In [100]: a[0] = 9

In [101]: a
Out[101]: array([9, 0], dtype=object)

In [102]: orig
Out[102]: 
array([[9, 0],
       [0, 0],
       [0, 0]], dtype=object)

但如果没有orig数组被保存/引用到其他地方,我看不出这是一个问题。查看差异的唯一方法是检查标志:

In [103]: a, b, c = np.zeros((3,2), dtype=np.object)

In [104]: a.flags.owndata
Out[104]: False

In [105]: a, b, c = [np.zeros((2,), dtype=np.object) for _ in xrange(3)]

In [106]: a.flags.owndata
Out[106]: True

答案 3 :(得分:0)

以下内容绝对是推荐,但很酷

locals().update({
    'x%d' % i : np.zeros((2,), dtype=np.object)
    for i in range(3)
})
print x2
=> array([0, 0], dtype=object)

但是,再次,不要这样做。改为使用列表(例如)。

相关问题