我有一个二维数组,我想填充代表功率的值,但我的问题在于代码的速度,因为二维数组是100x100大小而我不想先用100x100 zereos列表初始化它然后用值填充列表,而是直接用值填充100x100二维列表。我的代码显示在下面
x_list = np.linspace(min_x, max_x, (max_x - min_x)+1)
y_list = np.linspace(min_y, max_y, (max_y - min_y)+1)
X, Y = np.meshgrid(x_list, y_list)
Y = Y[::-1]
Z = [[0 for x in range(len(x_list))] for x in range(len(y_list))] #Z is the two-dimensional list containing powers of reach position in the structure to be plotted
for each_axes in range(len(Z)):
for each_point in range(len(Z[each_axes])):
Z[len(Z)-1-each_axes][each_point] = power_at_each_point(each_point, each_axes)
#The method power_at_each_point is the one that calculates the values in the two-dimensional array Z
我想做的一个例子是代替下面显示的内容:
Z_old = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]]
for each_axes in range(len(Z_old)):
for each_point in range(len(Z_old[each_axes])):
Z_old[len(Z_old)-1-each_axes][each_point] = power_at_each_point(each_point, each_axes)
我现在想要不用零来初始化Z_old数组,而是在迭代它时用值填充它,这将类似于下面所写的内容,尽管它的语法是非常错误的但是'是我最终想要达到的目标。
Z = np.zeros((len(x_list), len(y_list))) for Z[len(x_list) -1 - counter_1][counter_2] is equal to power_at_each_point(counter_1, counter_2] for counter_1 in range(len(x_list)) and counter_2 in range(len(y_list))]
以及power_at_each_point的方法如下所示,如果它可以帮助您了解我想要做的事情,则会使用它的相关方法:
#A method to calculate the power reached from one node to the other for contourf function
def cal_pow_rec_plandwall_contour(node_index_tx, receiver):
nodess_excel = xlrd.open_workbook(Node_file_location)
nodes_sheet = nodess_excel.sheet_by_index(0)
node_index_tx_coor = [nodes_sheet.cell_value(node_index_tx - 1, 3), nodes_sheet.cell_value(node_index_tx - 1, 4)] #just co-ordinates of a point
distance = cal_distance(node_index_tx_coor, receiver)
if distance == 0:
power_rec = 10 * (np.log10((nodes_sheet.cell_value(node_index_tx - 1, 0) * 1e-3)))
return power_rec #this is the power received at each position
else:
power_rec = 10 * (np.log10((nodes_sheet.cell_value(node_index_tx - 1, 0) * 1e-3))) - 20 * np.log10((4 * math.pi * distance * 2.4e9) / 3e8) - cal_wall_att([node_index_tx_coor, receiver])
return power_rec
def power_at_each_point(x_cord, y_coord): #A method to get each position in the structure and calculate the power reached at that position to draw the structure's contourf plot
fa = lambda xa: cal_pow_rec_plandwall_contour(xa, [x_cord, y_coord])
return max(fa(each_node) for each_node in range(1, len(Node_Positions_Ascending) + 1)) #Node_position_ascending is a list containing the co-ordinate positions of markers basically or nodes.
如果有人能告诉我怎样才能用顶部底部的值填充二维数组Z,就像我在那里做的那样,而不是先将二维数组设置为零,那将非常感激。
答案 0 :(得分:0)
好的,首先,您要创建NumPy数组,而不是列表列表。这几乎总是要小得多,而且工作速度要快一些。而且,更重要的是,它打开了向你的循环进行矢量化的大门,这使得它们能够更快地完成 lot 。所以,而不是:
Z_old = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]]
......这样做:
Z_old = np.zeros((3, 5))
但现在让我们看看我们是否可以对你的循环进行矢量化而不是修改值:
for each_axes in range(len(Z_old)):
for each_point in range(len(Z_old[each_axes])):
Z_old[len(Z_old)-1-each_axes][each_point] = each_point**2 + each_axes**2
此处未使用Z[…]
的初始值,因此我们不需要像您怀疑的那样预先填充0。每个点使用的 是r
和c
。 (为了简洁起见,我将Z_old
,each_axes
和each_point
重命名为Z
,r
和c
。 )特别是,您尝试将每个Z[len(Z)-1-r, c]
设置为r**2 + c**2
。
首先,让我们反转底片,以便您将每个Z[r, c]
设置为某种东西 - 在这种情况下为(len(Z)-1-r)**2 + c**2
。
那"某事"只是r
和c
值的函数。我们可以通过创建arange
来获得。特别是,arange(5)
只是数字0, 1, 2, 3, 4
的数组,而arange(5)**2
是正方形0, 1, 4, 9, 16
的数组。
唯一的问题是,为了得到一个3x5阵列,我们必须逐元素地添加两个2D阵列,一个3x1阵列和一个1x5阵列,反之亦然,但是我们有{2个1D阵列来自{ {1}}。好吧,我们可以arange
其中一个:
reshape
当然,你可以进一步简化这一点(显然你不需要Z_old = (3 - 1 - np.arange(3))**2 + (np.arange(5)**2).reshape((5, 1))
,你可以只添加一个没有3 - 1
的新轴),但希望直接显示它是怎样的对应于您的原始代码。