Pandas 替换列中距离度量值大于阈值的图元
考虑一个数据帧:Pandas 替换列中距离度量值大于阈值的图元,pandas,dataframe,for-loop,Pandas,Dataframe,For Loop,考虑一个数据帧: company | label comp1 fashion comp2 fashionitem comp3 fashionable comp4 auto comp5 autoindustry comp6 automobile comp6 food comp7 delivery 我想稍微清理一下标签,我使用了字符串距离: from diffli
company | label
comp1 fashion
comp2 fashionitem
comp3 fashionable
comp4 auto
comp5 autoindustry
comp6 automobile
comp6 food
comp7 delivery
我想稍微清理一下标签,我使用了字符串距离:
from difflib import SequenceMatcher
def distance(a, b):
return SequenceMatcher(None, a, b).ratio()
问题是,如何编写一个函数,在label
列的任意两个元素之间应用distance
函数,并在最后用最短的字符串替换所有类似的元素(距离高于某个阈值)
结果应该是:
company | label
comp1 fashion
comp2 fashion
comp3 fashion
comp4 auto
comp5 auto
comp6 auto
comp6 food
comp7 delivery
我正在考虑执行2 for循环,但我的数据集可能相当大,有没有一种有效的方法来实现这一点
编辑:在阅读下面的回复时,我意识到我犯了一个错误。条目的总数(公司数)很大,但唯一标签的总数很小,不到1000个。我想,你可以应用df.label(unique)
并使用它 创意
这种方法的思想是从阈值(ed)比率矩阵建立邻接矩阵。从邻接矩阵建立一个图,并从中得到连接的组件(集群)。获得所需的输出可能很棘手,但可以通过0.49的(绝对)阈值来实现
设置
from difflib import SequenceMatcher
import networkx as nx
import numpy as np
import pandas as pd
df = pd.DataFrame(data=[['comp1', 'fashion'],
['comp2', 'fashionitem'],
['comp3', 'fashionable'],
['comp4', 'auto'],
['comp5', 'autoindustry'],
['comp6', 'automobile'],
['comp6', 'food'],
['comp7', 'delivery']], columns=['company', 'label'])
def distance(a, b):
return SequenceMatcher(None, a, b).ratio()
代码
# get unique labels
labels = df['label'].unique()
# compute ratios
result = np.array([[distance(li, lj) for lj in labels] for li in labels])
# set diagonal to zero
result[np.arange(8), np.arange(8)] = 0
# build adjacency matrix
adjacency_matrix = (result > 0.49).astype(int)
# create graph
dg = nx.from_numpy_array(adjacency_matrix, create_using=nx.Graph)
# create mapping dictionary from connected components
mapping = {}
for component in nx.connected_components(dg):
group = labels[np.array(list(component))]
value = min(group, key=len)
mapping.update({label: value for label in group})
result = df.assign(label=df.label.map(mapping))
print(result)
输出
company label
0 comp1 fashion
1 comp2 fashion
2 comp3 fashion
3 comp4 auto
4 comp5 auto
5 comp6 auto
6 comp6 food
7 comp7 delivery
您的数据集有多大?@Erfan目前“仅”有大约500k个条目,但我认为总共可能有200-300万个条目。如果您愿意接受近似解,精确解至少需要50万次运算。类似的元素是否总是共享一个共同的前缀?@DanielMesejo,我希望有一个精确的函数,它也适用于少量不同的标签(<1000)。我在上面的问题中做了一个更正,因为我意识到不同标签的数量很小。在你上面的例子中,fashion、fashionitem形成一个集群,因此必须用其中最短的一个来替换它们?听起来很有趣,但我已经将其应用到我的实际数据帧中,并获得标签“TV”对于新专栏中的每个人。您使用了什么阈值?0.49,返回“vi”,0.60返回“tv”。我真的不明白为什么。试着看看组件的值是什么,根据你说的,似乎只有一个连接的组件。对于阈值为0.8,似乎效果很好。我会接受这个答案,谢谢。