简体   繁体   English

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

[英]assigning an object to multiple variables - python

Is it possible to assign a single numpy object to several variables in one go? 是否可以一次将单个numpy对象分配给多个变量?

For instance, I have many variables that I'd like to initiate with np.zeros((2,), dtype=np.object) 例如,我有很多要通过np.zeros((2,), dtype=np.object)

I thought of doing a,b,c = np.zeros((2,), dtype=np.object) but got a ValueError . 我想到做a,b,c = np.zeros((2,), dtype=np.object)但是得到了ValueError a=b=c=np.zeros((2,), dtype=np.object) doesn't work either because if I change one variable the others also change. a=b=c=np.zeros((2,), dtype=np.object)都不起作用,因为如果我更改一个变量,其他变量也会更改。

With three variables like the example above it isn't a problem to do it manually but when I have dozens it would be convenient to be able to do this in a more effient way. 有了上面示例中的三个变量,手动执行操作就没问题了,但是当我有几十个变量时,以一种更有效的方式进行操作将很方便。

EDIT - A more concrete example would be: 编辑-一个更具体的例子是:

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})

Use a list comprehension: 使用列表理解:

>>> 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

If you're planning to add dozens of variables like this, 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)}

In your actual code, there is no reason to have these variables just so you can insert them all into a dict. 在您的实际代码中,没有理由只具有这些变量,因此您可以将它们全部插入到dict中。 And there's also no reason to initialize the values to equal arrays in the first place just so you can then mutate them into the arrays you actually want. 而且,也没有理由首先将值初始化为相等的数组,这样您就可以将它们变异为实际需要的数组。 If you write everything in the obvious way, the problem you're trying to solve never even arises: 如果您以明显的方式编写所有内容,那么您尝试解决的问题就永远不会出现:

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})

If you think you need to pre-create and then mutate the arrays to guarantee that you get the results you want, as you claim in the comments… well, first, just run this code and you'll see that you get three 1D object arrays, not 2D arrays of something else. 如果您认为需要先创建然后对数组进行变异以确保获得所需的结果,那么就像在注释中声明的那样……好吧,首先,运行此代码,您将看到获得三个1D对象数组,而不是其他东西的2D数组。 But if you don't know how to determine that for yourself, and don't want to just try it and test, you can always explicitly specify the dtype (either as object , or as a complex type) to force it. 但是,如果您不知道如何自行确定,并且不想尝试并进行测试,则始终可以显式指定dtype (作为object或作为复杂类型)来强制使用它。

And meanwhile, even if you did need to pre-create the arrays (which, again, you don't), there would still be no reason to create dozens of separate variables and then put them in a dict after the fact. 同时,即使您确实需要预先创建数组(同样也不需要),仍然没有理由创建数十个单独的变量,然后将它们放入事件之后的dict中。 In other words, just do this: 换句话说,只需执行以下操作:

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

Or, if you really want entirely separate arrays for some reason instead of sliced out of a higher-dimensional array: 或者,如果出于某种原因确实想要完全独立的数组,而不是从更高维度的数组中切出:

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

And of course you can wrap this all up in a function if you're doing it multiple times. 当然,如果您多次执行此操作,则可以将其全部包装到一个函数中。

A nice way to make several arrays is to add the number of desired output arrays as the first dimension ( axis 0 ). 制作多个数组的一种好方法是将所需输出数组的数量添加为第一维( axis 0 )。 So, if you want three arrays of length two, filled with zeros of dtype object, you can do this: 因此,如果您想要三个长度为2的数组,并用dtype对象的零填充,则可以执行以下操作:

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

This works for any array, where the unpacking is from the first axis, for some examples: 对于某些数组,该数组适用于从第一个轴解包的数组,例如:

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

NB: This is not identical to doing 注意:这与这样做并不相同

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

Because in that case each of the arrays were created separately, and won't necessarily be contiguous in memory. 因为在这种情况下,每个数组都是单独创建的,因此不一定在内存中是连续的。 If you use the unpacking of a single array, the original array was first created as one single contiguous array, and the new arrays are just views of the original array. 如果使用单个数组的解压缩,则首先将原始数组创建为一个连续的数组,而新数组只是原始数组的视图。 You haven't saved the original array, so I can't see this in any effect, but if you did store, then split the array, you'd see they shared data: 您尚未保存原始数组,因此我看不到任何效果,但是如果您存储了存储然后拆分了数组,则会看到它们共享数据:

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)

But without the orig array being saved/referred to elsewhere, I can't see this being an issue. 但是如果没有将orig数组保存/引用到其他地方,我看不到这是一个问题。 The only way to see the difference is by checking the flags: 看到差异的唯一方法是检查标志:

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

The below is absolutely not recommended, but cool nevertheless 绝对建议使用以下内容,但仍然很酷

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

But, again, don't do it. 但是,再次,不要这样做。 Use a list (for example) instead. 请改用列表(例如)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM