Python熊猫:如何将字典的每个值与所有其他值进行最佳比较?

Python熊猫:如何将字典的每个值与所有其他值进行最佳比较?,python,dictionary,pandas,comparison,Python,Dictionary,Pandas,Comparison,我有一个字典“orgs_dict”,我想将每个值与所有值进行比较,因为我将所有值放在一个集合中,然后进行比较,如果它们相同,我将其添加到“final_hosts”字典中: orgs_dict = {'Ridgway School': 'ridgway','Ridgway Uni': 'ridgway', 'Aktieselskapet': 'aktieselskapet','Aktieselskapet_1': 'aktieselskapet', 'Chinese Education Assoc

我有一个字典“orgs_dict”,我想将每个值与所有值进行比较,因为我将所有值放在一个集合中,然后进行比较,如果它们相同,我将其添加到“final_hosts”字典中:

orgs_dict = {'Ridgway School': 'ridgway','Ridgway Uni': 'ridgway', 'Aktieselskapet': 'aktieselskapet','Aktieselskapet_1': 'aktieselskapet', 'Chinese Education Association Ex': 'chinese association ex', 'Gestora de Infraestructuras de Telecomunicaciones': 'gestora infraestructuras telecomunicaciones','Aktieselskapet_5': 'aktieselskapet'}
这是我的密码:

set_neworgs=set()
for key in orgs_dict.keys():
    set_neworgs.add(orgs_dict[key])

final_hosts = defaultdict(list)
for i in set_neworgs:
    for k,v in orgs_dict.items():
        if i == v:
            final_hosts[i].append(k) 

这很好,但当我的“orgs_dict”非常大时,需要3个小时才能完成。我想知道有谁知道一种更可选的方法吗?

您可以使用键作为列“new\u orgs”,值作为“hosts”构造df,然后使用
value\u counts()>1作为布尔过滤器,然后使用
isin
过滤本系列中存在的主机:

In [150]:

orgs_dict = {'Ridgway School': 'ridgway','Ridgway Uni': 'ridgway', 'Aktieselskapet': 'aktieselskapet','Aktieselskapet_1': 'aktieselskapet', 'Chinese Education Association Ex': 'chinese association ex', 'Gestora de Infraestructuras de Telecomunicaciones': 'gestora infraestructuras telecomunicaciones','Aktieselskapet_5': 'aktieselskapet'}
df =pd.DataFrame({'new_orgs':list(orgs_dict.keys()), 'hosts':list(orgs_dict.values())})
df
Out[150]:
                                         hosts  \
0                               aktieselskapet   
1                                      ridgway   
2                               aktieselskapet   
3                                      ridgway   
4                       chinese association ex   
5  gestora infraestructuras telecomunicaciones   
6                               aktieselskapet   

                                            new_orgs  
0                                   Aktieselskapet_1  
1                                     Ridgway School  
2                                   Aktieselskapet_5  
3                                        Ridgway Uni  
4                   Chinese Education Association Ex  
5  Gestora de Infraestructuras de Telecomunicaciones  
6                                     Aktieselskapet  

In [157]:

df[df['hosts'].isin((df['hosts'].value_counts()[df['hosts'].value_counts()> 1].index))]
Out[157]:
            hosts          new_orgs
0  aktieselskapet  Aktieselskapet_1
1         ridgway    Ridgway School
2  aktieselskapet  Aktieselskapet_5
3         ridgway       Ridgway Uni
6  aktieselskapet    Aktieselskapet
另一种方法是通过“主机”进行分组,然后计算“新组织”的数量,并使用此方法进行筛选:

In [167]:

df['host_count'] = df.groupby('hosts')['new_orgs'].transform('count')
df[df['host_count'] > 1]
Out[167]:
            hosts          new_orgs  host_count
0  aktieselskapet  Aktieselskapet_1           3
1         ridgway    Ridgway School           2
2  aktieselskapet  Aktieselskapet_5           3
3         ridgway       Ridgway Uni           2
6  aktieselskapet    Aktieselskapet           3
计时

在这个小样本集上,我得到

In [168]:

%%timeit
df['host_count'] = df.groupby('hosts')['new_orgs'].transform('count')
df[df['host_count'] > 1]
1000 loops, best of 3: 1.65 ms per loop

In [169]:

%timeit df[df['hosts'].isin((df['hosts'].value_counts()[df['hosts'].value_counts()> 1].index))]
1000 loops, best of 3: 1.49 ms per loop
所以差别不大,您当前的方法更快:

In [175]:

%%timeit
set_neworgs=set()
for key in orgs_dict.keys():
    set_neworgs.add(orgs_dict[key])
​
final_hosts = defaultdict(list)
for i in set_neworgs:
    for k,v in orgs_dict.items():
        if i == v:
            final_hosts[i].append(k) 
100000 loops, best of 3: 6.85 µs per loop

但是,它不能很好地扩展到您的实际数据集大小,而上述两种方法将

Python 2.7+:可以通过以下词典理解找到值相同的键:

{k: orgs_dict[k] for k in orgs_dict  if orgs_dict.values().count(orgs_dict[k])>1}
Python3.x:在调用
列表中包装
组织目录值()

{k: orgs_dict[k] for k in orgs_dict  if list(orgs_dict.values()).count(orgs_dict[k])>1}
输出:

{'Aktieselskapet_1': 'aktieselskapet', 'Ridgway School': 'ridgway', 'Aktieselskapet': 'aktieselskapet', 'Ridgway Uni': 'ridgway', 'Aktieselskapet_5': 'aktieselskapet'}
另一种方法: 在2.7+和3.x中,使用
集合
模块中的
计数器

from collections import Counter
c = Counter(orgs_dict.values()) # count values
{k : orgs_dict[k] for k in orgs_dict.keys() if c[orgs_dict[k]]>1}

因此,您想根据是否有2个或更多重复项来筛选dict?您的示例dict没有显示重复项,您关心这些键吗?@EdChum我编辑了示例dict。我想知道值相同的键。提示:
set\u neworgs=set(orgs\u dict.keys())
@MrE还感谢一个好提示。我猜瓶颈更多的是在比较方面。你有什么建议吗?谢谢EdChum,从不同的角度看数据,更明智。我刚刚尝试了第一种方法,但在某些情况下,我仍然会得到一个值为“hosts”(条件为>1)的“hosts”。你认为为什么会发生这种情况?你必须发布数据,以便我可以复制它,groupby方法有效吗?对不起,我犯了一个错误。它们都工作得很好。谢谢你,还有一个问题。如果不是“orgs_dict”的,而是有一组这样的dict,有不同的键:final_dict[key]=orgs_dict。我可以把你的代码放在final_dict中所有键的循环中吗?我可以为每个dict构造一个df,然后
concat
,或者将所有dict展平为一个dict,并从展平的dict中构造df see values,而不是keyshere@VidhyagatTributeTError:“dict_values”对象没有属性“count”。我在寻找值和键,寻找最重要的值same@Vidhya我在您的代码AttributeError中遇到了这个错误:“dict_values”对象没有属性“count”,我不知道为什么会出现属性错误(我使用的是Python 2.7.6)。我会更新的,这样你就有钥匙了。谢谢。因为我使用的是Python3.x