python-3.x 如何从多个布尔子状态数组中创建一个布尔状态数组(其中只有一个元素为True)?

jm81lzqq  于 2022-12-01  发布在  Python
关注(0)|答案(1)|浏览(115)

设置:

我正在尝试为pygame中内置的一个简单游戏构建一个学习代理,在这个游戏中,代理必须跟踪各种对象的sub_state;每个sub_state是一维布尔数组,其中可以具有任何/所有/零True值。作为最小工作示例,考虑以下内容:

import numpy as np

sub_state_a = np.array([
    False,
    ])
    # False,
    # True])

sub_state_b = np.array([
    True,
    ])
    # False,
    # True,
    # False,
    # False])

sub_state_c = np.array([
    True])

sub_states = [
    sub_state_a,
    sub_state_b,
    sub_state_c]

# for sub_state_index, sub_state in enumerate(sub_states):
#     print("\n .. SUB-STATE (index={}; shape={}):\n{}\n".format(
#         sub_state_index,
#         sub_state.shape,
#         sub_state))

因为这些3子状态中的每一者可仅具有2可能值中的一者(TrueFalse),唯一可能状态的总数为2 ** 3 = 8。换句话说,存在8个子状态的唯一组合,使得在任何给定时间/帧只有一个状态是X1 M10 N1 X。
通过该逻辑,如果存在1子状态而不是8,则将存在2 ** 1 = 2个可能的唯一状态(T或F);如果存在2个子状态而不是8,则将存在2 ** 2 = 4个可能的唯一状态(TT、TF、FT、FF);和/或其他信息。
下面的代码片段使用concatenated_sub_states初始化state数组。
第一次

问题:

我想使用sub_states中的布尔数组来选择数组states的索引,该索引应该被设置为True。当为concatenated_sub_states[0]=True时为states[1]=True,但对于所有其它指数为False;和/或其他信息。
我想有一种方法可以用itertools.groupbynumpy魔法来实现这一点,但我一直在想怎么做。如果问题不清楚,可以写什么函数来把sub_states作为输入,并输出应该设置为True的states的索引?
我一直在考虑的一种方法如下:

running_product = 1
for each sub_state in sub_states:
    index_loc = np.where(sub_state)\[0]
    running_product *= np.prod(index_loc)
offset = ... # ????
state_index = int(2 ** running_product - offset)
x9ybnkn6

x9ybnkn61#

如果我们把它们写成10而不是booleans,我们基本上得到一个二进制数(对于您的示例,它将是011)。一旦我们有了二进制字符串(称之为binary_num),我们可以通过int(binary_num, 2)将其转换为以10为底的数字。现在我们缺少中间部分,如何从一个布尔值数组转换为一个字符串,该字符串只是将布尔值连接起来。为此,我们使用函数np.array2string和关键字参数separator="",这样数字之间就没有空格了。把所有这些放在一起:

# one array with the values of the different lists stacked
# your example: np.array([False, True, True])
sub_states = np.hstack([sub_state_a, sub_state_b, sub_state_c]) 

# your example: '[011]'
sub_states = np.array2string(sub_states.astype(int), separator = "")

# your example: print(int("011",2)), which is just print(3)
print(int(sub_states.strip("[").strip("]"),2))

希望这对你有帮助。

相关问题