如何解决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'}
,
这是使用熊猫的另一种方式。我不确定它将如何扩展到 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 举报,一经查实,本站将立刻删除。