问题描述
我有字典:
{'a': ['b','c'],'b':['e','f'],'c':['g'],'h':['m','n']}
我希望字典根据相似性对其进行分组
这是我希望字典在处理后的外观:
{'a':['b','c','e','f','g'],'n']
}
有什么办法可以有效地做到这一点?我想将此字典转换为pandas数据框。
编辑:
这些实际上是映射。上面的字典意思是。 :
a = b,c b = e,f
因此, a = b,c,e,f 同样 h = m,n(不同的值映射)注意:这完全基于我正在设计的模型。
解决方法
不知道它是否是最有效的方法(可能不是),但是您可以尝试以下方法:
def merge_entries(input_dict):
to_delete = set()
for k,v in input_dict.items():
if k not in to_delete:
for x in v:
if x in input_dict.keys():
test[k]+=test[x]
to_delete.add(x)
for i in to_delete:
del input_dict[i]
return input_dict
test = {
'a': ['b','c'],'b':['e','f'],'c':['g'],'h':['m','n']
}
print (merge_entries(test))
我已经通过相似性来解释您的合并,方法是如果键x
的任何值与字典中的键y
匹配,然后将y
的值合并到x
编辑:
OP将演示数据集编辑为以下内容:
test ={'a': ['b','f','n'],'k':['c']}
在这种情况下,我将假设预期的答案是这两类:
[{'g','e','k','b','c','a'},{'h','n','m'}]
我还要假设字典格式是不相关的,因为在新的OP示例中,字典条目'k':['c']}
将由值c合并到第一组。因此,我将在列表中提供n
设置条目的答案。
def merge_entries2(input_dict):
results = []
count = 0
for k,v in input_dict.items():
if count == 0: #initial state add a group
nset=set(v)
nset.add(k)
results.append(nset)
count+=1
else:
for i,group in enumerate(results):
nset = set(v)
nset.add(k)
if k in group:
results[i] = results[i].union(nset)
break
else:
if len(nset.intersection(group)) > 0:
results[i]=results[i].union(nset)
break
else:
results.append(nset)
break
return results
test ={'a': ['b','k':['c']}
print (merge_entries2(test))
脚本的快速概述: 如果未定义任何组,请使用第一个词典条目中键值的组合值定义第一个组。然后,对于每个其他字典条目,使用组合的键和值创建一个新集合,并检查这些集合是否与任何现有集合相交,是否确实合并了它们,是否不创建新组。
,重新格式化字典有副作用,但是我相信这很明显。
d = {'a': ['b','b': ['e','c': ['g'],'h': ['m','n']}
for k in list(d.keys()):
# may have deleted the key,check..
if k in d.keys():
for i in list(d[k]):
# defined as another key,append and delete..
if i in d.keys():
d[k] += d[i]
del d[i]
# finally construct dataframe dict. list sizes vary so use {"col":{id:val}} format
df = pd.DataFrame({k:{i:v for i,v in enumerate(d[k])} for k in d.keys()})
print(d)
print(df.to_string(index=False))
输出(先是字典,然后是数据框)
{'a': ['b','g'],'n']}
a h
b m
c n
e NaN
f NaN
g NaN