假设您有一个结构化数组,例如如下所示:
import numpy as np
a = np.array(
[tuple([np.random.randint(100) for _ in range(3)]) for _ in range(100)],
dtype=[('var1', 'i4'), ('var2', 'i4'), ('var3', 'i4')]
)
现在,我只想访问此数组的特定子集/切片。例如这样:
interval = (10, 30)
b = a[
(a['var1'] >= interval[0]) & (a['var1'] <= interval[1])
]
到目前为止一切顺利。但是,如果我有对应于不同变量的可变数量的间隔怎么办?例如这样:
intervals = [('var1', 10, 30), ('var2', 20, 50)]
我无法对其进行硬编码,因为程序运行时间隔量会发生变化。但我想要的是这样的任意数量的间隔:
b = a[
((a[intervals[0][0]] >= intervals[0][1]) & (a[intervals[0][0]] <= intervals[0][2])) |
((a[intervals[1][0]] >= intervals[1][1]) & (a[intervals[1][0]] <= intervals[1][2]))
]
到目前为止,我唯一的想法是使用 for 循环
遍历间隔并创建一个字符串,然后可以使用 eval
执行该字符串,但我不太喜欢这个。有更好的解决办法吗?
string = 'a[((a[intervals[0][0]] >= intervals[0][1]) & (a[intervals[0][0]] ' \
'<= intervals[0][2]))'
for i in range(len(intervals[1:])):
string += f' | \n((a[intervals[{i+1}][0]] >= intervals[{i+1}][1]) & ' \
f'(a[intervals[{i+1}][0]] <= intervals[{i+1}][2]))'
string += ']'
b = eval(string)
最佳答案
您不需要为此问题生成代码。使用 functools.reduce
将 |
运算符应用于未知的一系列掩码。
import operator
from functools import reduce
mask = reduce(
operator.__or__, # the `|` operator
(
((a[var] >= lower) & (a[var] <= upper))
for var, lower, upper in intervals # arbitrary number of intervals
)
)
b = a[mask]
关于python - 如何在 Python 中创建可变代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59879316/