比较pandas中的列和它本身

2024-04-19 02:37:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧:

df = pd.DataFrame({'names': ['Mohit', 'Mimansa', 'Viseshini', 'Manoj', 'Manojj', 'Mohith', 'Mimi', 'Visesheni']})
df

names
0   Mohit
1   Mimansa
2   Viseshini
3   Manoj
4   Manojj
5   Mohith
6   Mimi
7   Visesheni

我试图将每个字符串与其他列中的其余字符串进行比较

我有一个函数partial_ratio,它接受两个字符串并返回相似百分比:

^{pr2}$

我想要的是字符串匹配至少为80%的行的索引。在

我试过了:

ratios = []
for row in df['names']:
    vals = df['names'].apply(lambda x: fuzz.partial_ratio(x, row))
    ratios.append(np.where(vals>80))
ratios

[(array([0, 5], dtype=int64),),
 (array([1], dtype=int64),),
 (array([2, 7], dtype=int64),),
 (array([3, 4], dtype=int64),),
 (array([3, 4], dtype=int64),),
 (array([0, 5], dtype=int64),),
 (array([6], dtype=int64),),
 (array([2, 7], dtype=int64),)]

有两个问题:

1)我使用for循环,因此对于更大的数据集,操作非常缓慢。使用一个序列的apply函数将每个字符串相互比较,然后返回另一个序列。使用np.where检索至少80%匹配的索引。在

2)在应用字符串时也使用字符串本身。。在

有没有熊猫的功能/方法或更好的方法来实现这一点:

   names     matches
0   Mohit        [5]
1   Mimansa      []
2   Viseshini    [7]
3   Manoj        [4]
4   Manojj       [3]
5   Moht Motwani [0]
6   Mimi         []
7   Visesheni    [2]

Tags: 数据字符串dfnamesarraydtypemimiint64
2条回答

您可以从list comprehension转换为numpy array循环和列出,因此可能的筛选器如果使用numpy.where筛选出相同的索引,则索引由{}创建:

from fuzzywuzzy import fuzz

ratios = []
for i, x in enumerate(df['names']):
    a = np.array([fuzz.partial_ratio(x, row) for row in df['names']])
    a = np.where(a > 80)[0]
    ratios.append(a[a != i])

df['rat'] = ratios
print (df)

       names  rat
0      Mohit  [5]
1    Mimansa   []
2  Viseshini  [7]
3      Manoj  [4]
4     Manojj  [3]
5     Mohith  [0]
6       Mimi   []
7  Visesheni  [2]

使用下面的代码块,所以只需为您想要的输出做一堆东西,它可能不可读,但仍然可以按预期工作,一堆apply和一些时髦的代码:-):

from fuzzywuzzy import fuzz
import pandas as pd
import random,ast
df = pd.DataFrame({'names': ['Mohit', 'Mimansa', 'Viseshini', 'Manoj', 'Manojj', 'Mohith', 'Mimi', 'Visesheni']})
it=iter(range(len(df['names'])))
df['matches']=df['names'].apply(lambda x: [i for i,v in enumerate(df['names']) if fuzz.partial_ratio(v,x)>80] if len([i for i,v in enumerate(df['names']) if fuzz.partial_ratio(v,x)>80])>1 else [])
df['matches']=df['matches'].astype(str)
df['count'] = df.groupby('matches').cumcount() + 1
df['matches']=df['matches'].map(ast.literal_eval)
df['matches']=df.apply(lambda x: ([x['matches'][-1]] if x['count']==1 else [x['matches'][0]]) if x['matches']!=[] else x['matches'],axis=1)
print(df)

输出:

^{pr2}$

解释:

  • 创建一个apply语句以按预期获取索引

  • 生成一个groupby以获取值的计数,每个值都将被计数,直到该值存在的行

  • 然后进行一系列更新'matches'列,并消除重复问题

相关问题 更多 >