[英]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.