如何将一维数组转换为二维数组?
How to convert a 1D array to a 2D array?
我正在编写代码来求解二维热方程。我在 x 维度上有 nx 点,在 y 维度上有 ny 点。 (nx 和 ny 是用户输入)。解决方案以形状数组 (nx*ny,) 的形式出现。但很自然地,我想将解决方案绘制为二维数组。所以我尝试将结果的值分配给另一个二维数组,如下所示:
# A is a (nx*ny, nx*ny) sparse square matrix of csc format. b is a (nx*ny,) NumPy array.
y = sp.linalg.bicgstab(A, b) # shape of y is (nx*ny,)
solution = np.zeros((nx, ny))
for i in range(0, ny):
for j in range(0, nx):
solution[i, j] = y[i + nx * j]
但这会引发错误:
TypeError: only size-1 arrays can be converted to Python scalars
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:/Users/USER/Desktop/Numerical Practice/FDM-2D Heat Equation-No Source.py", line 86, in <module>
main()
File "C:/Users/USER/Desktop/Numerical Practice/FDM-2D Heat Equation-No Source.py", line 77, in main
solution[i, j] = y[i + nx * j]
ValueError: setting an array element with a sequence.
Process finished with exit code 1
我哪里出错了,我该怎么做才能解决这个问题?我已经通过直接打印检查了初始结果(y)。 y 正确输出。解决后出现错误
P.S。如果我使用函数 sp.linalg.spsolve
而不是 sp.linalg.bicgstab
,它工作正常。但我正在探索稀疏迭代求解器,所以我希望使用 sp.linalg.bicgstab
.
我查阅了官方文档。事实证明,所有稀疏迭代求解器 return 两件事:解和收敛信息。如果直接写成y = sp.linalg.bicgstab(A, b)
,y就变成了一个形如(2,)的元组,第一个元素是解,第二个元素是收敛信息。我通过 y, exit_code = sp.linalg.bicgstab(A, b)
修复了它。现在它工作正常
您的代码有几个问题。
触发您观察到的错误的原因是 scipy.linalg.bicgstab()
的 return 值是 tuple
而不是您期望的 NumPy 数组。
另一个问题是您尝试访问形状为 (nx, ny)
的对象,索引 i, j
的范围分别为 0
到 ny
和 nx
.因此,除非您有 nx == ny
,否则上面的代码会在某些时候超出数组边界。
最后,所有这些都是通过显式循环完成的。然而,NumPy 提供了更好的工具来获得你想要的东西,特别是 np.reshape()
.
例如:
import numpy as np
nx = 800
ny = 1200
y = np.random.randint(0, 100, nx * ny)
def reshape_loops(y):
solution = np.zeros((nx, ny))
for i in range(0, nx):
for j in range(0, ny):
solution[i, j] = y[i + nx * j]
return solution
def reshape_np(y):
return np.reshape(y.copy(), (nx, ny), order='F')
print(np.allclose(reshape_loops(y), reshape_np(y)))
# True
%timeit reshape_loops(y)
# 1 loop, best of 3: 319 ms per loop
%timeit reshape_np(y)
# 1000 loops, best of 3: 1.25 ms per loop
矢量化方法快约 250 倍。
我正在编写代码来求解二维热方程。我在 x 维度上有 nx 点,在 y 维度上有 ny 点。 (nx 和 ny 是用户输入)。解决方案以形状数组 (nx*ny,) 的形式出现。但很自然地,我想将解决方案绘制为二维数组。所以我尝试将结果的值分配给另一个二维数组,如下所示:
# A is a (nx*ny, nx*ny) sparse square matrix of csc format. b is a (nx*ny,) NumPy array.
y = sp.linalg.bicgstab(A, b) # shape of y is (nx*ny,)
solution = np.zeros((nx, ny))
for i in range(0, ny):
for j in range(0, nx):
solution[i, j] = y[i + nx * j]
但这会引发错误:
TypeError: only size-1 arrays can be converted to Python scalars
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:/Users/USER/Desktop/Numerical Practice/FDM-2D Heat Equation-No Source.py", line 86, in <module>
main()
File "C:/Users/USER/Desktop/Numerical Practice/FDM-2D Heat Equation-No Source.py", line 77, in main
solution[i, j] = y[i + nx * j]
ValueError: setting an array element with a sequence.
Process finished with exit code 1
我哪里出错了,我该怎么做才能解决这个问题?我已经通过直接打印检查了初始结果(y)。 y 正确输出。解决后出现错误
P.S。如果我使用函数 sp.linalg.spsolve
而不是 sp.linalg.bicgstab
,它工作正常。但我正在探索稀疏迭代求解器,所以我希望使用 sp.linalg.bicgstab
.
我查阅了官方文档。事实证明,所有稀疏迭代求解器 return 两件事:解和收敛信息。如果直接写成y = sp.linalg.bicgstab(A, b)
,y就变成了一个形如(2,)的元组,第一个元素是解,第二个元素是收敛信息。我通过 y, exit_code = sp.linalg.bicgstab(A, b)
修复了它。现在它工作正常
您的代码有几个问题。
触发您观察到的错误的原因是 scipy.linalg.bicgstab()
的 return 值是 tuple
而不是您期望的 NumPy 数组。
另一个问题是您尝试访问形状为 (nx, ny)
的对象,索引 i, j
的范围分别为 0
到 ny
和 nx
.因此,除非您有 nx == ny
,否则上面的代码会在某些时候超出数组边界。
最后,所有这些都是通过显式循环完成的。然而,NumPy 提供了更好的工具来获得你想要的东西,特别是 np.reshape()
.
例如:
import numpy as np
nx = 800
ny = 1200
y = np.random.randint(0, 100, nx * ny)
def reshape_loops(y):
solution = np.zeros((nx, ny))
for i in range(0, nx):
for j in range(0, ny):
solution[i, j] = y[i + nx * j]
return solution
def reshape_np(y):
return np.reshape(y.copy(), (nx, ny), order='F')
print(np.allclose(reshape_loops(y), reshape_np(y)))
# True
%timeit reshape_loops(y)
# 1 loop, best of 3: 319 ms per loop
%timeit reshape_np(y)
# 1000 loops, best of 3: 1.25 ms per loop
矢量化方法快约 250 倍。