我有一个关于python和选择范围内元素的问题。
如果我有一个n行m矩阵,有n行和m列,我每列都有一个定义的范围(所以我有m分和最大值)。
现在我想选择那些所有值都在范围内的行。
查看以下示例:
input = matrix([[1, 2], [3, 4],[5,6],[1,8]])
boundaries = matrix([[2,1],[8,5]])
#Note:
#col1min = 2
#col1max = 8
#col2min = 1
#col2max = 5
print(input)
desired_result = matrix([[3, 4]])
print(desired_result)
这里有3行被丢弃,因为它们包含超出边界的值。
虽然我能够在给定数组的一个范围内获取值,但我无法有效地解决此问题。
感谢您的帮助。
答案 0 :(得分:0)
我相信有更优雅的解决方案,但我来到这里:
def foo(data, boundaries):
zipped_bounds = list(zip(*boundaries))
output = []
for item in data:
for index, bound in enumerate(zipped_bounds):
if not (bound[0] <= item[index] <= bound[1]):
break
else:
output.append(item)
return output
data = [[1, 2], [3, 4], [5, 6], [1, 8]]
boundaries = [[2, 1], [8, 5]]
foo(data, boundaries)
输出:
[[3, 4]]
我知道如果数组的大小与每个具体大小不匹配,则不会检查和引发异常。我把它留给OP实现这个。
答案 1 :(得分:0)
您的示例数据语法不正确matrix([[],..])
因此需要重新构建,如下所示:
matrix = [[1, 2], [3, 4],[5,6],[1,8]]
bounds = [[2,1],[8,5]]
我不确定“高效”的确切含义,但此解决方案具有可读性,计算效率和模块性:
# Test columns in row against column bounds or first bounds
def row_in_bounds(row, bounds):
for ci, colVal in enumerate(row):
bi = ci if len(bounds[0]) >= ci + 1 else 0
if not bounds[1][bi] >= colVal >= bounds[0][bi]:
return False
return True
# Use a list comprehension to apply test to n rows
print ([r for r in matrix if row_in_bounds(r,bounds)])
>>>[[3, 4]]
首先,我们为接受边界列表列表的行创建可重用的测试函数,元组可能更合适,但我按照您的规范坚持列表。
然后将测试应用于具有列表推导的n行矩阵。如果n超出bounds列索引或bounds列的索引为false,则使用提供的第一组边界。
将行迭代器保留在行解析器函数之外,可以根据需要执行从过滤后的元素中获取最小值/最大值的操作。这样,您就不需要为每个所需数据的操作定义新函数。