微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python pandas 递归查找相关名称

如何解决Python pandas 递归查找相关名称

我有一个如下所示的熊猫数据框:

                 vname               gname
0       Vishu Adhikari      Haren Adhikari
1            Viswa Roy           galen Roy
2            Vishu Ray           Deven Ray
3           Vasavi Ray          Yogesh Ray
4             Vina Ray           Suren Ray
...                ...                 ...
226498       Umesh Ray       Bhimachar Ray
226499     Umapada Roy   Umesh Chandra Roy
226500        Upen Ray       Bholanath Ray
226501       UTTAM ROY  HARISH CHANDRA ROY
226502        USHA ROY     CHHATRAPATI ROY

我的目标是将每一行分类为 H 或 M 并找到 H 类别中的所有名称。 H 的定义:所有带有“roy”字样的名称和所有带有 roy 作为名称一部分的名称以及所有相关名称(我们现在可以忽略类别 M)。 示例:在 galen Roy 中,galen 将归类为 H。此外,所有出现“galen”的名称(在 df['names'] 列中)都需要归类为 H,依此类推。

这是我试过的:

df.vname = df.vname.str.lower()
df.gname = df.gname.str.lower()
df['names'] = df['vname'] + ' ' + df['gname']
names_h = ['roy']

#get all names related to roy recursively

def get_relnames(df,name,names_rel):
    
    for i,row in df.iterrows():
        names = row['names'].split(' ') #gives list of words
        if name in names:
            for x in names:
                if x not in names_rel and len(x) >2 and ')' not in x:
                    names_rel.append(x)
                    print(len(names_rel))
                    get_relnames(df,x,names_rel)

    print(names_rel)
    print(len(names_rel))

get_relnames(df,'roy',names_h)

但是它太慢了,大约一个小时后会抛出错误“RecursionError:相比之下超出了最大递归深度”。 实现这一目标的最佳方法是什么?任何帮助将不胜感激。

编辑: 20 行数据框的样本。

names_h = ['roy']

                  vname                 gname                                    names
0        vishu adhikari        haren adhikari            vishu adhikari haren adhikari
1             viswa roy             galen roy                      viswa roy galen roy
2             vishu roy             deven roy                      vishu roy deven roy
3            vasavi ray            yogesh ray                    vasavi ray yogesh ray
4              vina ray             suren ray                       vina ray suren ray
5     vimalkumar barman   rajendr nath barman    vimalkumar barman rajendr nath barman
6         vaishakhi ray             jiten ray                  vaishakhi ray jiten ray
7   vishma dev adhikary     haripada adhikary    vishma dev adhikary haripada adhikary
8             vishu ray           lakhiya ray                    vishu ray lakhiya ray
9             vivek roy         lalit ch. roy                  vivek roy lalit ch. roy
10     vibhas singh ray    niranjan simah ray      vibhas singh ray niranjan simah ray
11   vijayakumar sarkar  mahesh chandr sarkar  vijayakumar sarkar mahesh chandr sarkar
12            vishu ray          shrikant ray                   vishu ray shrikant ray
13           vihsma roy           bishadu roy                   vihsma roy bishadu roy
14          vaswati roy            sirish roy                   vaswati roy sirish roy
15       vishu adhikari       gotalu adhikari           vishu adhikari gotalu adhikari
16     vishmadeb barman         bhaben barman           vishmadeb barman bhaben barman
17          vina barman         ramesh barman                vina barman ramesh barman
18            vishu ray      hemendranath ray               vishu ray hemendranath ray
19            vishu das            haleya das                     vishu das haleya das

输出

names_h = ['roy','vishu','deven','adhikari','haren','viswa','galen','vivek','lalit','ray','shrikant','vihsma','bishadu','vaswati','sirish','gotalu','hemendranath','das','haleya','vasavi','yogesh','vina','suren','lakhiya','barman','bhaben','vishmadeb','ramesh','rajendr','nath']

vishu 是列表,因为它与 roy 相关(在第 3 行的名称列中),hemendranath 在列表中,因为它与 vishu(在最后一行)。 需要为 220k+ 行的整个数据帧递归查找所有这些相关词。

我的代码运行良好,并为较小的数据帧提供了预期的输出,但对于较大的数据帧,它需要花费数小时并最终因错误而崩溃。

解决方法

您可以使用 var circle_f3a483b3a7ba46748ac935d3995f4f6b = L.circle( [-16.0,0.0] ).addTo(feature_group_1c28eff59e394734be54cf676a09eae1); var circle_a01d1791063145b18b439bd7687bc97f = L.circle( [-11.3137,11.3137],).addTo(feature_group_1c28eff59e394734be54cf676a09eae1); var layer_control_aec3ac6e0e424b74a19b4c9d1c78ffeb = { base_layers : { },overlays : { "Roads" : geo_json_cae0ea33c63e4c438678d293e5c32c0d,"Intersections" : feature_group_1c28eff59e394734be54cf676a09eae1,},};

构建所有名称对 (networkx) ,代表图的边。现在,您必须添加 egdes 但您必须将元组列表的列表展平为一个简单的元组列表 (itertools.combinations)。现在,您只需使用 itertoos.chain.from_iterable 从节点 'roy' 获取连接的节点。

node_connected_component
import itertools
import networkx as nx
from networkx.algorithms.components import node_connected_component

edges = df['names'].str.findall(r'\w{3,}') \
                   .apply(lambda x: list(itertools.combinations(x,2)))
G = nx.Graph()
G.add_edges_from(itertools.chain.from_iterable(edges))
names_h = node_connected_component(G,'roy')

绘制:

>>> names_h
{'adhikari','barman','bhaben','bishadu','das','deven','galen','gotalu','haleya','haren','hemendranath','jiten','lakhiya','lalit','nath','niranjan','rajendr','ramesh','ray','roy','shrikant','simah','singh','sirish','suren','vaishakhi','vasavi','vaswati','vibhas','vihsma','vimalkumar','vina','vishmadeb','vishu','viswa','vivek','yogesh'}

enter image description here

,

这是使用熊猫的另一种方式。我不确定它将如何扩展到 220k 行。

all_names = df["names"].str.lower().str.split().explode()

targets = ["roy"]
n_old = None
while len(targets) != n_old:   
    n_old = len(targets)
    targets = all_names[all_names.isin(targets).groupby(level=0).any()]
    targets = targets.unique()
print(targets)

这个想法是依靠熊猫字符串方法而不是手动循环,这几乎总是很慢。我没有删除“ch”。我会让你去做那件事。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。