Python 字典中数组的交集
Python intersection of arrays in dictionary
我有这样的数组字典:
y_dict= {1: np.array([5, 124, 169, 111, 122, 184]),
2: np.array([1, 2, 3, 4, 5, 6, 111, 184]),
3: np.array([169, 5, 111, 152]),
4: np.array([0, 567, 5, 78, 90, 111]),
5: np.array([]),
6: np.array([])}
我需要在我的字典中查找截取数组:y_dict
。
作为第一步,我从空数组中清除了字典,例如
dic = {i:j for i,j in y_dict.items() if np.array(j).size != 0}
所以,dic
有以下观点:
dic = { 1: np.array([5, 124, 169, 111, 122, 184]),
2: np.array([1, 2, 3, 4, 5, 6, 111, 184]),
3: np.array([169, 5, 111, 152]),
4: np.array([0, 567, 5, 78, 90, 111])}
为了找到拦截,我尝试使用元组方法,如下所示:
result_dic = list(set.intersection(*({tuple(p) for p in v} for v in dic.values())))
实际结果为空列表:[]
;
预期结果应为:[5, 111]
你能帮我在字典中找到数组的交集吗?谢谢
您发布的代码过于复杂且错误,因为需要进行一次额外的内部迭代。你想做的事:
result_dic = list(set.intersection(*(set(v) for v in dic.values())))
或有 map
且没有 for
循环:
result_dic = list(set.intersection(*(map(set,dic.values()))))
结果
[5, 111]
- 迭代值(忽略键)
- 将每个 numpy 数组转换为
set
(转换为 tuple
也可以,但是 intersection
无论如何都会将它们转换为集合)
- 通过参数解包将批次传递给
intersection
我们甚至可以通过在每个数组上创建集合并使用 filter
:
过滤掉空集合来摆脱步骤 1
result_dic = list(set.intersection(*(filter(None,map(set,y_dict.values())))))
这是为了单行,但在现实生活中,表达式可能会被分解,以便它们更具可读性和可评论性。这种分解还可以帮助我们避免在不传递任何参数(因为没有非空集)时发生的崩溃,这会破坏相交集的智能方法(首先在 Best way to find the intersection of multiple sets? 中描述)。
只要预先创建列表,只有当列表不为空时才调用交集。如果为空,则只创建一个空集:
non_empty_sets = [set(x) for x in y_dict.values() if x.size]
result_dic = list(set.intersection(*non_empty_sets)) if non_empty_sets else set()
你应该在这里使用 numpy 的交集,而不是直接在 Python 中。并且您需要为空交叉路口添加特殊处理。
>>> intersection = None
>>> for a in y_dict.values():
... if a.size:
... if intersection is None:
... intersection = a
... continue
... intersection = np.intersect1d(intersection, a)
...
>>> if intersection is not None:
... print(intersection)
...
[ 5 111]
对于 intersection is None
的情况,这意味着 y_dict
中的所有数组的大小为零(没有元素)。在这种情况下,交集没有明确定义,您必须自己决定代码应该在这里做什么 - 可能会引发异常,但这取决于用例。
我有这样的数组字典:
y_dict= {1: np.array([5, 124, 169, 111, 122, 184]),
2: np.array([1, 2, 3, 4, 5, 6, 111, 184]),
3: np.array([169, 5, 111, 152]),
4: np.array([0, 567, 5, 78, 90, 111]),
5: np.array([]),
6: np.array([])}
我需要在我的字典中查找截取数组:y_dict
。
作为第一步,我从空数组中清除了字典,例如
dic = {i:j for i,j in y_dict.items() if np.array(j).size != 0}
所以,dic
有以下观点:
dic = { 1: np.array([5, 124, 169, 111, 122, 184]),
2: np.array([1, 2, 3, 4, 5, 6, 111, 184]),
3: np.array([169, 5, 111, 152]),
4: np.array([0, 567, 5, 78, 90, 111])}
为了找到拦截,我尝试使用元组方法,如下所示:
result_dic = list(set.intersection(*({tuple(p) for p in v} for v in dic.values())))
实际结果为空列表:[]
;
预期结果应为:[5, 111]
你能帮我在字典中找到数组的交集吗?谢谢
您发布的代码过于复杂且错误,因为需要进行一次额外的内部迭代。你想做的事:
result_dic = list(set.intersection(*(set(v) for v in dic.values())))
或有 map
且没有 for
循环:
result_dic = list(set.intersection(*(map(set,dic.values()))))
结果
[5, 111]
- 迭代值(忽略键)
- 将每个 numpy 数组转换为
set
(转换为tuple
也可以,但是intersection
无论如何都会将它们转换为集合) - 通过参数解包将批次传递给
intersection
我们甚至可以通过在每个数组上创建集合并使用 filter
:
result_dic = list(set.intersection(*(filter(None,map(set,y_dict.values())))))
这是为了单行,但在现实生活中,表达式可能会被分解,以便它们更具可读性和可评论性。这种分解还可以帮助我们避免在不传递任何参数(因为没有非空集)时发生的崩溃,这会破坏相交集的智能方法(首先在 Best way to find the intersection of multiple sets? 中描述)。
只要预先创建列表,只有当列表不为空时才调用交集。如果为空,则只创建一个空集:
non_empty_sets = [set(x) for x in y_dict.values() if x.size]
result_dic = list(set.intersection(*non_empty_sets)) if non_empty_sets else set()
你应该在这里使用 numpy 的交集,而不是直接在 Python 中。并且您需要为空交叉路口添加特殊处理。
>>> intersection = None
>>> for a in y_dict.values():
... if a.size:
... if intersection is None:
... intersection = a
... continue
... intersection = np.intersect1d(intersection, a)
...
>>> if intersection is not None:
... print(intersection)
...
[ 5 111]
对于 intersection is None
的情况,这意味着 y_dict
中的所有数组的大小为零(没有元素)。在这种情况下,交集没有明确定义,您必须自己决定代码应该在这里做什么 - 可能会引发异常,但这取决于用例。