繁体   English   中英

Python 乘以多维 arrays 值

[英]Python multiply multidimensional arrays values

我有以下数组:

values = [1, 1, 1, [1,2], 1,[3,4,5],[6,7]]

我想将其中的每个数字乘以5 以下代码无效:

import numpy as np
m = np.array(values)
print(m * 5)

output:

[5 5 5 list([1, 2, 1, 2, 1, 2, 1, 2, 1, 2]) 5
 list([3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5])
 list([6, 7, 6, 7, 6, 7, 6, 7, 6, 7])]

正如评论中提到的,numpy 在这方面很糟糕,因为 numpy 是为每个维度中长度相等的 arrays 设计的:您无法将列表转换为 numpy 数组。 但这正是awkward的 package 的设计目的:请参阅https://github.com/scikit-hep/awkward-1.0#readme

使用pip install awkward1

然后:

import awkward1 as ak

values = [1, 1, 1, [1,2], 1,[3,4,5],[6,7]]
result = ak.Array(values) * 5
print(result.tolist())

产量

[5, 5, 5, [5, 10], 5, [15, 20, 25], [30, 35]]

另一种方法是使用老式的递归 function:

values = [1, 1, 1, [1,2], 1,[3,4,5],[6,7]]

def listmult(x, c): 
   out = [] 
   for v in x: 
       if isinstance(v, list): 
           out.append(listmult(v, c)) 
       else: 
           out.append(v*c)
   return out
           
print(listmult(values, 5))

[5, 5, 5, [5, 10], 5, [15, 20, 25], [30, 35]]

In [232]: alist = [1, 1, 1, [1,2], 1,[3,4,5],[6,7]]                                                  

1.19开始, numpy警告从列表中创建数组:

In [233]: np.array(alist)                                                                            
/usr/local/bin/ipython3:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
  #!/usr/bin/python3
Out[233]: 
array([1, 1, 1, list([1, 2]), 1, list([3, 4, 5]), list([6, 7])],
      dtype=object)

请注意,此数组包含数字和列表:

In [234]: np.array(alist, object)                                                                    
Out[234]: 
array([1, 1, 1, list([1, 2]), 1, list([3, 4, 5]), list([6, 7])],
      dtype=object)

对于 object dtype 数组,它迭代(以 python 的速度)元素,并将操作委托给元素自己的方法。 对于列表*5表示复制:

In [235]: np.array(alist, object)*5                                                                  
Out[235]: 
array([5, 5, 5, list([1, 2, 1, 2, 1, 2, 1, 2, 1, 2]), 5,
       list([3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5]),
       list([6, 7, 6, 7, 6, 7, 6, 7, 6, 7])], dtype=object)

现在,如果列表包含 arrays 而不是列表:

In [236]: alist = [1, 1, 1, np.array([1,2]), 1,np.array([3,4,5]),np.array([6,7])]                    
In [237]: np.array(alist, object)                                                                    
Out[237]: 
array([1, 1, 1, array([1, 2]), 1, array([3, 4, 5]), array([6, 7])],
      dtype=object)

现在乘法适用于数组元素 - 使用数字乘法。

In [238]: np.array(alist, object)*5                                                                  
Out[238]: 
array([5, 5, 5, array([ 5, 10]), 5, array([15, 20, 25]), array([30, 35])],
      dtype=object)

object dtype arrays 上的数学是命中或未命中,具体取决于元素的类型。 它对某些人有效,对其他人无效,这取决于元素如何实现操作。 即使在它起作用的地方,速度也更像是列表理解而不是多维数组。

In [244]: timeit np.array(alist, object)*5                                                           
13.3 µs ± 333 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [245]: timeit [i*5 for i in alist]                                                                
6.43 µs ± 140 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [246]: timeit np.array([i*5 for i in alist],object)                                               
9.98 µs ± 47.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

恐怕您的数据结构不允许该操作。 至少不是 numpy。如果将不同维度的列表列表转换为 numpy 数组,则生成的数据类型将为object ,但没有数字数据类型(int、float 等):

>>> import numpy as np
>>> np.array([1, [1]])
array([1, list([1])], dtype=object)

因此, numpy 不会将数组中的内容视为数字,因此无法广播数字运算。 确保所有输入数据的维数相等,以便在将列表列表转换为 numpy 数组后, dtype是数字数据类型:

>>> np.array([[1], [1]]).dtype
dtype('int64')

暂无
暂无

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

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