>

데이터 프레임이 있습니다 :

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

각 문자열을 다른 열의 나머지 문자열과 비교하려고합니다

2 개의 문자열을 가져와 유사성 비율을 반환하는 partial_ratio 함수가 있습니다.

from fuzzywuzzy import fuzz
fuzz.partial_ratio('Mohit', 'Moht Motwani')
>>80

내가 원하는 것은 문자열 일치가 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 루프를 사용하고 있기 때문에 더 큰 데이터 세트의 경우 작업 속도가 매우 느려집니다. 각 문자열은 계열의 적용 함수를 사용하여 서로 비교되고 다른 계열이 반환됩니다. np.where 를 사용하여 80 % 이상의 일치 인덱스를 검색합니다. .

2) apply 함수를 사용하면 문자열도 자체와 비교됩니다.

팬더 기능/방법 또는 이것을 달성하는 더 좋은 방법이 있습니까 :

  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]

  • 답변 # 1

    당신은 numpy array 로 변환하고 목록 이해에서 고리를 나열 할 수 있습니다 이므로 numpy.where 로 가능한 filterinf  부울 인덱싱으로 동일한 인덱스를 필터링하면 enumerate 에 의해 인덱스가 생성됩니다. :

    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]
    
    

  • 답변 # 2

    아래의 코드 덩어리를 사용하십시오. 원하는 출력을 위해 많은 작업을 수행하면 읽을 수는 없지만 여전히 예상대로 작동합니다. s 및 펑키 코드 :-) :

    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)
    
    

    설명하려면 :

    와이즈 비즈 만들기  예상대로 색인을 얻는 것에 대한 진술

    와이즈 비즈 만들기  값의 개수를 얻기 위해 모든 값은 값이 존재하는 행까지 계산됩니다

    그런 다음 names matches count 0 Mohit [5] 1 1 Mimansa [] 1 2 Viseshini [7] 1 3 Manoj [4] 1 4 Manojj [3] 2 5 Mohith [0] 2 6 Mimi [] 2 7 Visesheni [2] 2 를 업데이트하기 위해 많은 작업을 수행하십시오.  열에서 중복 문제를 제거

    apply

관련 자료

  • 이전 geometry - 알고리즘 - 기하학적 모양에는 다른 모양이 포함될 수 있습니다
  • 다음 javascript - 두 개의 키보드 키가 동시에 다운되는 것을 감지