一个大型 numpy 数组(5 列 300 万行)——如何选择同时满足多个条件的行? Python 3.8.8
One large numpy array (3mil rows on 5 columns) - how to pick rows that meet several conditions at the same time? Python 3.8.8
def func(data):
A = np.zeros([len(data), 5], np.int16)
for i in range(len(data)):
if(data[i, 1] >= -10 and data[i, 1] <= -13 and
data[i, 3] >= -20 and data[i, 3] <= -22):
A[i] = data[i]
elif(data[i, 1] >= -16 and data[i, 1] <= -19 and
data[i, 3] >= -24 and data[i, 3] <= --30):
A[i] = data[i]
.... (for another similar 8 elif conditions)
else:
continue
return A[~np.all(A == 0, axis=1)]
func(data)
问题:
我有一个大的 NumPy 数组,我需要提取满足这些条件的整行(不仅仅是索引或其值)。代码确实 运行 但速度很慢。这不是问题,但我必须阅读另外 800 个文件,然后执行其他任务。
如何优化这个功能?
提前谢谢你。
我已经制作了一个您可以尝试的工作版本。它摆脱了 for
循环,并且不需要您创建一个与 data
大小相同的全新数组 A
;在我的版本中,A
从 0 行开始,然后根据需要添加,这应该有助于节省 space。该函数也在某种程度上进行了矢量化,这意味着我不会手动遍历每一行。
def func(data):
# The array A must have the same number of columns as the data array. If you know this beforehand, then just use that; otherwise, replace 5 with data.shape[1].
A = np.zeros((0,5))
# mask1 contains the indices where these conditions are all met. After the mask is found, the rows in data with indices in mask1 are essentially appended to A.
mask1 = np.where((data[:,1] >= -10) & (data[:,1] <= -13) & (data[:,3] >= -20) & (data[:,3] <= -22))
A = np.concatenate((A, data[mask1]), axis=0)
# Do the same for all the other conditions.
mask2 = np.where((data[:,1] <= -19) & (data[:,3] >= -24) & (data[:,3] <= -30))
A = np.concatenate((A, data[mask2]), axis=0)
.... (for all other conditions)
return A
还有一件事:我对 data[i, 1] >= -10 and data[i, 1] <= -13
如何计算为 True 感到有点困惑,因为 -13 小于 -10.Same 和 data[i, 3] >= -20 and data[i, 3] <= -22
。也许您不小心翻转了标志,或者需要切换到 >=
和 <=
标志?
你有一个错字(--30
而不是 -30
),以防你错过了。我并不是想吹毛求疵,我只是不想让你陷入困境,为什么你的代码在你 运行 时不工作。对不起,如果我表现得很刻薄,我不想成为。
无论如何,如果您需要任何说明,请告诉我!
P.S。我为 side-scrolling 感到非常抱歉;我不确定如何修复它。
我的解决方案与 AJH 非常接近,但我相信它更简单一些,您不需要在内存中保留完整尺寸的 A
帧。不确定它有多大变化,但它占用的内存少了一点。
def func(data):
condition_1 = ((data[:, 1] <= -10) & (data[:, 1] >= -13) & (data[:, 3] <= -20) & (data[:, 3] >= -22))
condition_2 = ((data[:, 1] <= -16) & (data[:, 1] >= -19) & (data[:, 3] <= -24) & (data[:, 3] >= -30))
mask = (condition_1 | condition_2)
return data[mask]
然后只需添加您需要的所有条件即可。
有关 &
是 and
和 |
是 or
的信息,虽然我发现完整关键字更易于使用,但实际上它不适用于 numpy arrays
。
def func(data):
A = np.zeros([len(data), 5], np.int16)
for i in range(len(data)):
if(data[i, 1] >= -10 and data[i, 1] <= -13 and
data[i, 3] >= -20 and data[i, 3] <= -22):
A[i] = data[i]
elif(data[i, 1] >= -16 and data[i, 1] <= -19 and
data[i, 3] >= -24 and data[i, 3] <= --30):
A[i] = data[i]
.... (for another similar 8 elif conditions)
else:
continue
return A[~np.all(A == 0, axis=1)]
func(data)
问题: 我有一个大的 NumPy 数组,我需要提取满足这些条件的整行(不仅仅是索引或其值)。代码确实 运行 但速度很慢。这不是问题,但我必须阅读另外 800 个文件,然后执行其他任务。
如何优化这个功能? 提前谢谢你。
我已经制作了一个您可以尝试的工作版本。它摆脱了 for
循环,并且不需要您创建一个与 data
大小相同的全新数组 A
;在我的版本中,A
从 0 行开始,然后根据需要添加,这应该有助于节省 space。该函数也在某种程度上进行了矢量化,这意味着我不会手动遍历每一行。
def func(data):
# The array A must have the same number of columns as the data array. If you know this beforehand, then just use that; otherwise, replace 5 with data.shape[1].
A = np.zeros((0,5))
# mask1 contains the indices where these conditions are all met. After the mask is found, the rows in data with indices in mask1 are essentially appended to A.
mask1 = np.where((data[:,1] >= -10) & (data[:,1] <= -13) & (data[:,3] >= -20) & (data[:,3] <= -22))
A = np.concatenate((A, data[mask1]), axis=0)
# Do the same for all the other conditions.
mask2 = np.where((data[:,1] <= -19) & (data[:,3] >= -24) & (data[:,3] <= -30))
A = np.concatenate((A, data[mask2]), axis=0)
.... (for all other conditions)
return A
还有一件事:我对 data[i, 1] >= -10 and data[i, 1] <= -13
如何计算为 True 感到有点困惑,因为 -13 小于 -10.Same 和 data[i, 3] >= -20 and data[i, 3] <= -22
。也许您不小心翻转了标志,或者需要切换到 >=
和 <=
标志?
你有一个错字(--30
而不是 -30
),以防你错过了。我并不是想吹毛求疵,我只是不想让你陷入困境,为什么你的代码在你 运行 时不工作。对不起,如果我表现得很刻薄,我不想成为。
无论如何,如果您需要任何说明,请告诉我!
P.S。我为 side-scrolling 感到非常抱歉;我不确定如何修复它。
我的解决方案与 AJH 非常接近,但我相信它更简单一些,您不需要在内存中保留完整尺寸的 A
帧。不确定它有多大变化,但它占用的内存少了一点。
def func(data):
condition_1 = ((data[:, 1] <= -10) & (data[:, 1] >= -13) & (data[:, 3] <= -20) & (data[:, 3] >= -22))
condition_2 = ((data[:, 1] <= -16) & (data[:, 1] >= -19) & (data[:, 3] <= -24) & (data[:, 3] >= -30))
mask = (condition_1 | condition_2)
return data[mask]
然后只需添加您需要的所有条件即可。
有关 &
是 and
和 |
是 or
的信息,虽然我发现完整关键字更易于使用,但实际上它不适用于 numpy arrays
。