二维数组的乘积之和python
The sum of the products of a two-dimensional array python
我有 2 个包含一百万个元素的数组(根据具有每个像素亮度的图像创建)
我需要得到一个数字,它是同名数组元素的乘积之和。也就是说,A(1,1) * B(1,1) + A(1,2) * B(1,2)...
在循环中,python从循环(j1)中取出最后一个变量的值并开始运行通过它,然后将倒数第二个变量加1并再次运行最后一个,依此类推.我怎样才能让它计算同名的元素?
res1, res2 - 数组(特别是 - numpy.ndarray)
或许这方面有现成的功能,但我需要尽可能开放,没有现成的。
sum = 0
for i in range(len(res1)):
for j in range(len(res2[i])):
for i1 in range(len(res2)):
for j1 in range(len(res1[i1])):
sum += res1[i][j]*res2[i1][j1]
解决方案 1:
import numpy as np
a,b = np.array(range(100)), np.array(range(100))
print((a * b).sum())
方案二(更开放,因为使用了pd.DataFrame):
import pandas as pd
import numpy as np
a,b = np.array(range(100)), np.array(range(100))
df = pd.DataFrame(dict({'col1': a, 'col2': b}))
df['vect_product'] = df.col1 * df.col2
print(df['vect_product'].sum())
在我的回答的第一部分,我将解释如何直接修复您的代码。您的代码几乎是正确的,但在逻辑上存在一个大错误。在我回答的第二部分,我将解释如何使用 numpy
解决您的问题。 numpy
是 标准 python 包来处理数字数组。如果您要处理大量数字,没有理由不使用 numpy。
修复您的代码
您的代码使用 4 个嵌套的 for
循环,索引 i
和 j
迭代第一个数组,索引 i1
和 j1
迭代第二个数组。
因此,您将第一个数组中的每个元素 res1[i][j] 与第二个数组中的每个元素 res2[i1][j1] 相乘。这不是你想要的。您只想将第一个数组中的每个元素 res1[i][j]
与第二个数组中的相应元素 res2[i][j]
相乘:您应该对第一个和第二个数组使用相同的索引。因此应该只有两个嵌套的 for
-loops.
s = 0
for i in range(len(res1)):
for j in range(len(res1[i])):
s += res1[i][j] * res2[i][j]
请注意,我将变量称为 s
而不是 sum
。这是因为 sum
是 python 中的内置函数的名称。强烈建议隐藏内置名称。这是内置列表:https://docs.python.org/3/library/functions.html;不要使用该列表中的名称命名变量。
现在,一般来说,在 python 中,我们不喜欢在 for-loop 中使用 range(len(...))
。如果您阅读 the official tutorial and its section on for
loops,它表明 for
-loop 可用于直接迭代元素,而不是索引。
例如,这里是如何在一个数组上迭代,对数组中的元素求和,而不使用 range(len(...))
和索引:
# sum the elements in an array
s = 0
for row in res1:
for x in row:
s += x
这里row
是整行,x
是一个元素。我们根本不参考指数。
looping
的有用工具是内置函数 zip
和 enumerate
:
enumerate
如果您需要访问元素及其索引,则可以使用;
zip
可用于同时迭代两个数组。
我不会展示 enumerate
的示例,但是 zip
正是您所需要的,因为您想要迭代两个数组:
s = 0
for row1, row2 in zip(res1, res2):
for x, y in zip(row1, row2):
s += x * y
你也可以使用内置函数 sum
来写这一切而没有 +=
并且没有初始 = 0
:
s = sum(x * y for row1,row2 in zip(res1, res2) for x,y in zip(row1, row2))
使用numpy
正如我在简介中提到的,numpy
是一个标准的 python 包,用于处理数字数组。一般来说,使用 numpy 对数组的操作比核心 python 中的数组循环要快得多。另外,使用 numpy 的代码通常比仅使用 core python 的代码更容易阅读,因为有很多有用的函数和方便的符号。例如,这里有一个简单的方法来实现你想要的:
import numpy as np
# convert to numpy arrays
res1 = np.array(res1)
res2 = np.array(res2)
# multiply elements with corresponding elements, then sum
s = (res1 * res2).sum()
相关文档:
使用 numpy 的两个简单快速的选项是:(A*B).sum()
和 np.dot(A.ravel(),B.ravel())
。第一种方法对 A
和 B
的 element-wise 乘法的所有元素求和。 np.sum()
默认为sum(axis=None)
,所以我们会得到一个数字。在第二种方法中,您在两个矩阵中创建一维视图,然后应用 dot-product 方法获取单个数字。
import numpy as np
A = np.random.rand(1000,1000)
B = np.random.rand(1000,1000)
s = (A*B).sum() # method 1
s = np.dot(A.ravel(),B.ravel()) # method 2
第二种方法应该非常快,因为它不会创建 A
和 B
的新副本,而是查看它们,因此不会分配额外的内存。
我有 2 个包含一百万个元素的数组(根据具有每个像素亮度的图像创建) 我需要得到一个数字,它是同名数组元素的乘积之和。也就是说,A(1,1) * B(1,1) + A(1,2) * B(1,2)... 在循环中,python从循环(j1)中取出最后一个变量的值并开始运行通过它,然后将倒数第二个变量加1并再次运行最后一个,依此类推.我怎样才能让它计算同名的元素? res1, res2 - 数组(特别是 - numpy.ndarray) 或许这方面有现成的功能,但我需要尽可能开放,没有现成的。
sum = 0
for i in range(len(res1)):
for j in range(len(res2[i])):
for i1 in range(len(res2)):
for j1 in range(len(res1[i1])):
sum += res1[i][j]*res2[i1][j1]
解决方案 1:
import numpy as np
a,b = np.array(range(100)), np.array(range(100))
print((a * b).sum())
方案二(更开放,因为使用了pd.DataFrame):
import pandas as pd
import numpy as np
a,b = np.array(range(100)), np.array(range(100))
df = pd.DataFrame(dict({'col1': a, 'col2': b}))
df['vect_product'] = df.col1 * df.col2
print(df['vect_product'].sum())
在我的回答的第一部分,我将解释如何直接修复您的代码。您的代码几乎是正确的,但在逻辑上存在一个大错误。在我回答的第二部分,我将解释如何使用 numpy
解决您的问题。 numpy
是 标准 python 包来处理数字数组。如果您要处理大量数字,没有理由不使用 numpy。
修复您的代码
您的代码使用 4 个嵌套的 for
循环,索引 i
和 j
迭代第一个数组,索引 i1
和 j1
迭代第二个数组。
因此,您将第一个数组中的每个元素 res1[i][j] 与第二个数组中的每个元素 res2[i1][j1] 相乘。这不是你想要的。您只想将第一个数组中的每个元素 res1[i][j]
与第二个数组中的相应元素 res2[i][j]
相乘:您应该对第一个和第二个数组使用相同的索引。因此应该只有两个嵌套的 for
-loops.
s = 0
for i in range(len(res1)):
for j in range(len(res1[i])):
s += res1[i][j] * res2[i][j]
请注意,我将变量称为 s
而不是 sum
。这是因为 sum
是 python 中的内置函数的名称。强烈建议隐藏内置名称。这是内置列表:https://docs.python.org/3/library/functions.html;不要使用该列表中的名称命名变量。
现在,一般来说,在 python 中,我们不喜欢在 for-loop 中使用 range(len(...))
。如果您阅读 the official tutorial and its section on for
loops,它表明 for
-loop 可用于直接迭代元素,而不是索引。
例如,这里是如何在一个数组上迭代,对数组中的元素求和,而不使用 range(len(...))
和索引:
# sum the elements in an array
s = 0
for row in res1:
for x in row:
s += x
这里row
是整行,x
是一个元素。我们根本不参考指数。
looping
的有用工具是内置函数 zip
和 enumerate
:
enumerate
如果您需要访问元素及其索引,则可以使用;zip
可用于同时迭代两个数组。
我不会展示 enumerate
的示例,但是 zip
正是您所需要的,因为您想要迭代两个数组:
s = 0
for row1, row2 in zip(res1, res2):
for x, y in zip(row1, row2):
s += x * y
你也可以使用内置函数 sum
来写这一切而没有 +=
并且没有初始 = 0
:
s = sum(x * y for row1,row2 in zip(res1, res2) for x,y in zip(row1, row2))
使用numpy
正如我在简介中提到的,numpy
是一个标准的 python 包,用于处理数字数组。一般来说,使用 numpy 对数组的操作比核心 python 中的数组循环要快得多。另外,使用 numpy 的代码通常比仅使用 core python 的代码更容易阅读,因为有很多有用的函数和方便的符号。例如,这里有一个简单的方法来实现你想要的:
import numpy as np
# convert to numpy arrays
res1 = np.array(res1)
res2 = np.array(res2)
# multiply elements with corresponding elements, then sum
s = (res1 * res2).sum()
相关文档:
使用 numpy 的两个简单快速的选项是:(A*B).sum()
和 np.dot(A.ravel(),B.ravel())
。第一种方法对 A
和 B
的 element-wise 乘法的所有元素求和。 np.sum()
默认为sum(axis=None)
,所以我们会得到一个数字。在第二种方法中,您在两个矩阵中创建一维视图,然后应用 dot-product 方法获取单个数字。
import numpy as np
A = np.random.rand(1000,1000)
B = np.random.rand(1000,1000)
s = (A*B).sum() # method 1
s = np.dot(A.ravel(),B.ravel()) # method 2
第二种方法应该非常快,因为它不会创建 A
和 B
的新副本,而是查看它们,因此不会分配额外的内存。