[英]Numpy indexing using an array of booleans
I have the following array which indicates whether or not to take a certain item:我有以下数组,指示是否接受某个项目:
import numpy as np
test_array = np.array([[0, 0, 1],
[1, 1, 0],
[1, 1, 1]])
The array I want to index is this one:我要索引的数组是这个:
classes = ['a', 'b', 'c']
This is what the result should be:结果应该是这样的:
[['c'], ['a', 'b'], ['a', 'b', 'c']]
How can this be done?如何才能做到这一点?
I would start with something like that:我会从这样的事情开始:
result = []
for row in test_array:
partial_result = []
for i in range(3):
if row[i] == 1:
partial_result.append(classes[i])
result.append(partial_result)
print(result)
Results with:结果:
[['c'], ['a', 'b'], ['a', 'b', 'c']]
In Python, we prefer list comprehension over loops, so time to improve:在 Python 中,我们更喜欢列表理解而不是循环,所以需要改进:
print([[classes[i] for i, val in enumerate(row) if val] for row in test_array])
enumerate
is an in-build function which takes an iterable object as a parameter and returns iterable of tuples (index, element) for all elements in the original iterable, so enumerate(row)
will return (0, [0, 0, 1]), (1, [1, 1, 0]) and (2, [1, 1, 1]). enumerate
是一个内置 function ,它采用可迭代的 object 作为参数并返回原始迭代中所有元素的元组(索引,元素)的迭代,因此enumerate(row)
将返回 (0, [0, 0, 1] )、(1, [1, 1, 0]) 和 (2, [1, 1, 1])。
for i, val in enumerate(row) if val
will work, because 1s
are interpreted as True
in Python and 0s
as False
. for i, val in enumerate(row) if val
将起作用,因为在 Python 中1s
被解释为True
,而0s
被解释为False
。
[[classes[i] for i, val in enumerate(row) if val] for row in test_array]
^ create a list of elements based on some original list ------->^
^ each element of that list will be a list itself.
^ elements of that inner lists will be objects from classes list
^ for each pair (i, element) from enumerate(row) take this ith
element, but just if val == 1 ^
You could do the following:您可以执行以下操作:
import numpy as np
test_array = np.array([[0, 0, 1],
[1, 1, 0],
[1, 1, 1]])
classes = ['a', 'b', 'c']
lookup = dict(enumerate(classes))
result = [[lookup[i] for i, e in enumerate(arr) if e] for arr in test_array]
print(result)
Output Output
[['c'], ['a', 'b'], ['a', 'b', 'c']]
I would do it as this:我会这样做:
result = []
for array in test_array:
result.append([classes[i] for i,value in enumerate(array ) if value ])
In one line you can do:在一行中,您可以执行以下操作:
print ([[c for (x, c) in zip(l, classes) if x] for l in test_array])
The answers I've seen so far range from awkward to, quite frankly, baffling, so here is a straightforward solution.到目前为止,我看到的答案从尴尬到坦率地说,令人费解,所以这里有一个简单的解决方案。
import np
arr = np.array([[0, 0, 1], [1, 1, 0], [1, 1, 1]])
arr_bools = arr.astype(np.bool)
lookup_lst = np.array(['a', 'b', 'c'])
res = [lookup_lst[row].tolist() for row in arr_bools]
This can be done by matrix multiplication:这可以通过矩阵乘法来完成:
[*map(list, test_array.astype('O')@classes)]
# [['c'], ['a', 'b'], ['a', 'b', 'c']]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.