【问题标题】:Numpy ndenumerate is incredibly slow. Is there a quicker way of using conditions on arrays in numpy?Numpy ndenumerate 非常慢。有没有更快的方法在 numpy 中对数组使用条件?
【发布时间】:2015-04-25 00:13:05
【问题描述】:

我有 26 个数据数组,我正在处理非常大的数组,所以我想加快这个过程。这段代码实际上可以工作并实现了我想要它实现的目标,但是速度非常慢。

我想要代码做的是:

查看两个数组并选择满足或不满足特定条件的单元格。如果满足该条件,那么我想通过编辑并从另一个数组中获取值来更改这些单元格中的值。数组中的所有值都需要更新以反映这些变化。

我下面的代码可能看起来有点混乱,但这里是这样。这是我的慢代码:

active_layer # An array

active_layer_volumes = [] # List of 7 arrays
active_layer_proportions = [] # List of 7 arrays

inactive_layer # Array

inactive_layer_volumes = [] # List of 7 arrays
inactive_layer_proportions = [] # List of 7 arrays

# Calculate the lower and upper limits for the volume of the active layer
al_upper_volume_limit = 5
al_lower_volume_limit = 1

# Count the grainsizes as the model works through them
grain_size_counter = 1    

# Set up some empty arrays to hold the new values 
new_active_layer_total = np.zeros_like(active_layer)
new_inactive_layer_total = np.zeros_like(inactive_layer)

# Iterate through the 24 arrays in order
for active_layer_proportion, active_layer_volume, inactive_layer_proportion, inactive_layer_volume in izip(active_layer_volumes, active_layer_proportions,inactive_layer_volumes, inactive_layer_proportions):

    # Iterate through all of the cells in the active layer checking to see if certain conditions are met 
    for [i, j], depth in np.ndenumerate(active_layer): # Iterate through the cells 

        if active_layer[i, j] >= al_upper_volume_limit: # check to see if the volume in that cell is greater than 5m3
           inactive_layer_volume[i, j] = (20 * active_layer_proportion[i, j]) + inactive_layer_volume[i, j] # add 20cm proportion of that grainsize to the active layer
           active_layer_volume[i, j] = (active_layer[i, j] - 20) * active_layer_proportion[i, j] 

        elif active_layer[i, j] < al_lower_volume_limit and inactive_layer[i, j] > 0: # check to see if the volume in that cell is greater than 5m3        
            active_layer_volume[i, j] = (20 * inactive_layer_proportion[i, j]) + active_layer_volume[i, j]                      
            inactive_layer_volume[i, j] = inactive_layer_volume[i, j] - (20 * inactive_layer_proportion[i, j])

    # Increment a counter as the loop goes through the arrays                      
    grain_size_counter + 1

    # Add the new calculated volumes to a running total array
    new_active_layer_total += active_layer_volume
    new_inactive_layer_total += inactive_layer_volume

【问题讨论】:

  • 听起来你想要np.where 函数...
  • 我认为masked arrays 可能会做你想做的事。您可以根据条件创建掩码,然后对提醒进行操作。
  • 谢谢,我现在只看蒙面数组。一旦我使用了掩码数组,我可以覆盖原始数组中的值吗?

标签: python arrays loops numpy


【解决方案1】:

您可以将ndenumerate 上的内部循环替换为以下矢量化表达式:

# Array B contains True/False for the condition and is subsequently 
# used as Boolean index.
B = (active_layer >= al_upper_volume_limit)
inactive_layer_volume[B] += 20 * active_layer_proportion[B]
active_layer_volume[B] = (active_layer[B] - 20) * active_layer_proportion[B]

# The "not B" does the "else" part of the elif statement it replaces
B = ~B & (active_layer < al_lower_volume_limit) & (inactive_layer > 0)
active_layer_volume[B] += 20 * inactive_layer_proportion[B]                      
inactive_layer_volume[B] -= 20 * inactive_layer_proportion[B]

【讨论】:

  • True/False 数组的使用非常好谢谢我没想到这个谢谢
猜你喜欢
  • 2021-01-08
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 2014-09-23
  • 1970-01-01
  • 2019-11-14
  • 2019-03-30
  • 2011-08-11
相关资源
最近更新 更多