Döngüyü devam ettirme

Arkadaşlar selamlar,

fuzzywuzzy ile bir eşleştirme üzerinde çalışıyorum.

import pandas as pd
from fuzzywuzzy import fuzz
from fuzzywuzzy import process

bizim = pd.read_csv('x_bizim.csv')
karsilastirma = pd.read_csv('x_tumu.csv')

# DataFrame lerden isimleri çıkartma
df1_names = list(bizim.isim.unique())
df2_names = list(karsilastirma.isim.unique())

# Eşleşme puanını döndürme 
def match_names(name, list_names, min_score=0):
    max_score = -1
    max_name = ''
    for x in list_names:
        score = fuzz.ratio(name, x)
        if (score > min_score) & (score > max_score):
            max_name = x
            max_score = score
    return (max_name, max_score)

# eşleşme döngüsü
urunler = []
for x in df1_names:
    match = match_names(x, df2_names, 84)
    if match[1] >= 84:
        bizden = str(x)
        eslesen = str(match[0])
        oran = str(match[1])
        urunler.append([bizden, eslesen, oran])

df = pd.DataFrame(urunler,columns = ["bizim","genel","oran"])
df.to_csv('yeni.csv', encoding='utf-8', header=None, mode='a', index=False)

print(df)

2 farklı csv dosyamda bir takım ürün isimleri var ve birbiriyle verdiğim oranda eşleşmeyi sağladımı yeni biz dizi oluşturup dosyaya kaydediyor.

Ama sorun şu ki df1_names dizisinden bir elemanın karşığından bir sonuç bulunca diziden ikinci elemana geçiyor. Ama df2_names listesinden daha fazla sonuç bulabilir. Mesela %95 uyuşan buldu listenin altında %90 uyuşanda olabilir %100 uyuşan da. Sorun şu ki bulur bulmaz diziden ikinci olan için çalışmayı sürdürüyor.

Bu sorunu nasıl giderebilirim?
Teşekkürler

Kim? Nerede? Ornek?

match_names buldugu en iyi 1 sonucu donduruyor?

Hangi listenin? Neyle uyusan? Ornek?

Ne yapmasi lazim?


bkz: Soru Sorarken Sıkça Düşülen Hatalar #7

2 Beğeni
                                                 isim  fiyat         kaynak       tarih
0           10 Bölmeli Yumurta Viyolü Seti - 100 Adet  150.0  Ambalajpazari  11/07/2022
1           12 Bölmeli Yumurta Viyolü Seti - 100 Adet  200.0  Ambalajpazari  11/07/2022
2           15 Bölmeli Yumurta Viyolü Seti - 100 Adet  214.0  Ambalajpazari  11/07/2022
3                  2 Bölmeli Alüminyum Kap - 100 Adet  154.0  Ambalajpazari  11/07/2022
4    2 Bölmeli Film Yapıştırmalı Gıda Kabı - 400 Adet  766.0  Ambalajpazari  11/07/2022
..                                                ...    ...            ...         ...
457         Tek Kullanımlık Şeffaf Eldiven - 100 Adet    6.0  Ambalajpazari  11/07/2022
458       Vinyl Eldiven Pudrasız Büyük (L) - 100 Adet   42.0  Ambalajpazari  11/07/2022
459       Vinyl Eldiven Pudrasız Büyük (L) - 100 Adet   48.0  Ambalajpazari  11/07/2022
460       Vinyl Eldiven Pudrasız Küçük (S) - 100 Adet   48.0  Ambalajpazari  11/07/2022
461        Vinyl Eldiven Pudrasız Orta (M) - 100 Adet   48.0  Ambalajpazari  11/07/2022

bu birinci csv

                                                   isim    fiyat        kaynak       tarih
0        1000 cc Salata - Waffle Kabı Set  ( 240 Adet )   876.16  Ambalajstore  09/07/2022
1         1000 cc Salata - Waffle Kabı Set  ( 40 Adet )   175.12  Ambalajstore  09/07/2022
2                  160 cc Çaycı Kup Bardak ( 100 Adet )    22.27  Ambalajstore  09/07/2022
3                 160 cc Çaycı Kup Bardak ( 2000 Adet )   373.06  Ambalajstore  09/07/2022
4                   180 cc Kristal Bardak ( 1000 Adet )   552.39  Ambalajstore  09/07/2022
...                                                 ...      ...           ...         ...
6665        Sızdırmaz Baklava-güllaç Kabı 1000 Cc 50'li   778.95      Trendyol  11/07/2022
6666    Sızdırmaz Kap 1500 Gr Yüksek Kapak Paket 100'lü  1250.00      Trendyol  11/07/2022
6667  Plastik Sızdırmaz Kap 2000 gr Cc Bombe Yüksek ...   779.90      Trendyol  11/07/2022
6668  Şeffaf Kapaklı Sızdırmaz Gıda Kap Kase 100 Ad ...   464.91      Trendyol  11/07/2022
6669                         1000cc Sızdırmaz Kap 100lü   570.00      Trendyol  11/07/2022

bu da ikinci csv dosyası.

                                               bizim                                            genel oran
0          10 Bölmeli Yumurta Viyolü Seti - 100 Adet                   10 Bölmeli Yumurta Viyolü Seti   85
1          12 Bölmeli Yumurta Viyolü Seti - 100 Adet                   12 Bölmeli Yumurta Viyolü Seti   85
2          15 Bölmeli Yumurta Viyolü Seti - 100 Adet                   15 Bölmeli Yumurta Viyolü Seti   85
3                2 Bölmeli Hamburger Seti - 180 Adet       2 Bölmeli Hamburger Kabı Seti ( 100 Adet )   86
4             3 Bölmeli Kapaklı Kebap Kabı - 25 Adet           3 Bölmeli Kapaklı Kebap Kabı (75 Adet)   92
5       3 Bölmeli Kapaklı Kebap Kabı Siyah - 25 Adet           3 Bölmeli Kapaklı Kebap Kabı (75 Adet)   85
6             4 Bölmeli Kapaklı Kebap Kabı - 25 Adet         4 Bölmeli Kapaklı Kebap Kabı ( 75 Adet )   92
7             4 Bölmeli Kapaklı Kebap Kabı - 50 Adet         4 Bölmeli Kapaklı Kebap Kabı ( 75 Adet )   92
8       4 Bölmeli Kapaklı Kebap Kabı Siyah - 25 Adet               4 Bölmeli Kapaklı Kebap Kabı Siyah   87
9                 Alüminyum Kapak 1000 gr - 100 Adet             Alüminyum Kapak 1000 Gr ( 100 Adet )   91
10                Alüminyum Kapak 1500 gr - 100 Adet              Alüminyum Kapak 500 Gr ( 100 Adet )   90
11             Alüminyum Kapak 250-350 gr - 100 Adet          Alüminyum Kapak 250-350 Gr ( 100 Adet )   92
12                 Alüminyum Kapak 500 gr - 100 Adet              Alüminyum Kapak 500 Gr ( 100 Adet )   91
13            Alüminyum Krem Karamel Kabı - 100 Adet             Alüminyum Krem Karamel Kabı 100 Adet   97
14                  Alüminyum Künefe Kabı - 100 Adet                  Alüminyum Künefe Kabı 100 Adet.   95
15           Alüminyum Künefe Kabı Kapağı - 100 Adet              Alüminyum Künefe Kap+Kapak 100 Adet   86
16                     Alüminyum Sup Kase - 100 Adet                      Alüminyum Sup Kase 100 Adet   96
17                Alüminyum Sütlaç Kasesi - 100 Adet                   Alüminyum Sütlaç Kase 100 Adet   94
18         Alüminyum Sütlaç Kasesi Kapağı - 100 Adet                   Alüminyum Sütlaç Kase 100 Adet   85
19  Ayaklı Tatlı Kasesi Bombe Kapak 200 cc - 50 Adet  Ayaklı Tatlı Kasesi Bombe Kapak 200 cc 600 Adet   95
20            Baklava-Güllaç Kabı 1000 cc - 100 Adet         Baklava-Güllaç Kabı 1000 Gr ( 100 Adet )   90
21             Baklava-Güllaç Kabı 500 cc - 100 Adet          Baklava-Güllaç Kabı 500 Gr ( 100 Adet )   89
22                  Dondurma Kasesi 500 gr - 40 Adet                  Dondurma Kasesi 500 Gr 400 Adet   92
23                      Gıda Kasesi Kapağı - 50 Adet                      Gıda Kasesi Kapağı 400 Adet   91
24              Gıda Kasesi Şeffaf 1000 ml - 50 Adet              Gıda Kasesi Şeffaf 1000 ml 300 Adet   93
25               Gıda Kasesi Şeffaf 500 ml - 50 Adet               Gıda Kasesi Şeffaf 500 ml 400 Adet   93
26  Karton Dondurma Kasesi Kapağı 100 cc - 1100 Adet      Karton Dondurma Kasesi 100 cc ( 1000 Adet )   86
27                     Peynir Kabı 500 cc - 100 Adet                  Peynir Kabı 500 Gr ( 100 Adet )   87
28                     Karton Bardak 12 oz - 50 Adet                  Karton Bardak 12 Oz ( 80 Adet )   87
29                      Karton Bardak 4 oz - 50 Adet                      Karton Bardak 4 Oz 500 Adet   91
30                      Alüminyum Kuaför Folyo 15 cm                   Alüminyum Kuaför Folyo 1000 Gr   86
31                   Palet Streci 17 Mikron 10x300 m                  Palet Streci 17 Mikron 10x300 M   97
32                      Palet Streci 17 Mikron 50 cm                     Palet Streci 17 Mikron 50 cm  100
33                                  Streç Film 30 cm                                 Streç Film 300 m   94
34                                  Streç Film 45 cm                                  Streç Film 15 m   90
35                      Streç Film 8 Mikron 45x150 m              İLKA Streç Film 8 Mikron 45 x 180 m   86
36                      Streç Film 9 Mikron 45x300 m             Green Streç Film 9 Mikron 45 x 300 m   88
37                              Yanmaz Fırın Torbası                        Yanmaz Fırın Torbası 8"Li   89

Bu da döndürdüğü sonuç.

Birinci csv’den “10 Bölmeli Yumurta Viyolü Seti - 100 Adet” ile döngüye başlıyor ve ikinci csv’den if match[1] >= 84: karşığını yakayalınca br sonraki (ilk csv nin ikinici sırasındaki) satır ile devam ediyor.

Sorun şu ki “10 Bölmeli Yumurta Viyolü Seti - 100 Adet” ikinci csv de başka karşılık daha bulabilir. Ama şu an ki döngü bulup bir sonrakini geçiyor, başka var mı diye bakmıyor.

Umarım açıklayıcı olmuştur

Evet, ama match_names ilk parametreyi ikinci parametre listesindeki her seyle fuzz.ratio’liyor.

Kodun yapisina bakarsak ic ice iki for loop var ve df1_names’deki her eleman df2_names’deki her elemanla karsilasiyor. Yanlis okumadiysam.

Yok hocam her elemanla karşılaşmıyor. Mesela daha çok sonuç bulabilmesi için fuzz.ratio yu token_set_ratio ile değiştirdim. Sonuçları aldıktan sonra elle denemeler yaptım.
Mesela bana verdiği sonuçta ilk listedeki

“4 Bölmeli Kapaklı Kebap Kabı - 25 Adet”

ile ikinci listedeki

“4 Bölmeli Kapaklı Kebap Kabı (75 Adet)”

nı %97 oranla yakalıyor ama ikinci listede daha aşağılarda olan

“4 Bölmeli Kapaklı Kebap Kabı Siyah”

ile de %90 uyuşmasına rağmen bunu almıyor. Yani dediğim gibi ilk listeden bir tane yakaladı mı devamına bakmadan listeden ikinciyle, üçüncüyle… devam ediyor.

Bence sorun burada gibi.
Senin döngü max_name ve max_score u eziyor ezdiği için sen 84 den yüksek en son değeri alıyorsun. max_name ve max_score bir list yapıp onların içinden 84 den büyük olanları toplarsan daha doğru bir sonuç elde edersin. Ya da dic de yapabilirsin artık hangisi uygunsa.

Evet, dedigim gibi en yuksek skorlu eslesmeyi donduruyor. (& and olacak bu arada)

Emin misin?

:slight_smile: tabiki eminim

farklı bir fonksiyon yazdım. fuzzwuzzy nin process ini kullanarak. Ama burada da sorunlar var.

from fuzzywuzzy import fuzz
from fuzzywuzzy import process
import pandas as pd

bizim = pd.read_csv('x_bizim.csv')
karsilastirma = pd.read_csv('x_tumu.csv')

# isimleri gruplama ve index atama
grup = karsilastirma.groupby('isim')
grup = karsilastirma.set_index(["tarih"])

print(grup)

df1_names = list(bizim.isim.unique())
df2_names = list(grup.isim.unique())

yeni=[]
# skorlara göre çekme
def islem(query):
    islem=process.extract(query, df2_names, scorer=fuzz.ratio, limit=6)
    yeni.append(islem)

for i in range(len(bizim)):
    query=(bizim.loc[i, "isim"])
    match = islem(query)

df=pd.DataFrame(yeni, columns=['1','2','3','4','5','6'])
df.to_csv('test.csv', encoding='utf-8', mode='a', index=False)

print(df)

Bu kez benim listemdeki her bir satır için diğer listedeki tüm elemanlara bakıyor. ben burada limit değeri 6 olarak verdim. 6 taneye kadar eşleştirmeyi başarıyla yapıyor (yüksek skordan düşük skora doğru)

Ancak bu kez problem eğer döndürmeden tek olarak versem fonksiyondan örnek olarak (10 Bölmeli Yumurta Viyolü Seti, 85) şeklinde dönüyor ve bunu df ye atacağım zaman yeni=pd.DataFrame(islem, columns=['isim','oran']) şeklinde df içine alabiliyorum. fonksiyonun içine döngü ile atınca 6 sütünluk bir dönüş oluyor ve her bir sütun içeriği ('10 Bölmeli Yumurta Viyolü Seti', 85) olduğundan işlem yapmam da sorunlu oluyor.
islem fonksiyonunu nasıl düzenlemeliyim ki

sorulan   cevap
soru 1    cevap1
soru 1    cevap2
soru 1    cevap3
soru 1    cevap4
soru 1    cevap5
soru 1    cevap6

şeklinde dönüş alayım.

Olmaman gerektigini ima ediyordum:

“tabiki” hic olma. Beni ornek al: Bu hafta gordugum 125. for loop. Butun elemanlara bakip en yuksek skorlusunu aliyor. Cok kullandigim bir pattern. Yine de “loop yarida kesiliyor” diyince “belki atladigim, gormedigim bir sey vardir” diyorum.

Kod calistirilabilir olmadigi icin (bkz: Soru Sorarken Sıkça Düşülen Hatalar #7) iki print koyup deneyemiyorum, gosteremiyorum. Kodu calistirabilen tek kisi olarak senin sorumlulugun tam olarak nasil calistigini dogru bir sekilde aktarmak.

Ayni varsayim hatasi diger post’ta da var bu arada: For döngüsünde aynı elemanı tekrarlarmak

for loop’lari durup dururken yarida kesilmez. Boyle doga ustu bir olay yasaniyorsa bunun oldugunu kanitlamak senin sorumlulugun.

O zaman kanıtlayalım:
process fuzzywuzzy’nin toplu iş yapan fonksiyonu. Tek bir karşılaştırma metnini bir dizi içinde eşleştirmeye yarıyor. Ben de denememi bu fonksiyon üzerinden yapıyorum.

from fuzzywuzzy import fuzz
from fuzzywuzzy import process
import pandas as pd

karsilastirma = pd.read_csv('x_tumu.csv')
grup = karsilastirma.groupby('isim')
grup = karsilastirma.set_index(["tarih"])
df2_names = list(grup.isim.unique())
query="4 Bölmeli Kapaklı Kebap Kabı - 25 Adet"


islem=process.extract(query, df2_names, scorer=fuzz.token_sort_ratio, limit=6)

print(islem)

Bunun döndürdüğü sonuç:

[('3 Bölmeli Kapaklı Kebap Kabı (75 Adet)', 91), ('4 Bölmeli Kapaklı Kebap Kabı ( 75 Adet )', 91), ('4 Bölmeli Kapaklı Kebap Kabı (75 Adet)', 91), ('4 Bölmeli Kapaklı Kebap Kabı Siyah', 79), ('Özge Plastik 4 Bölmeli Kapaklı Kebap Kabı', 73), ('Özge Plastik 4 Bölmeli Kapaklı Sushi Kabı 300 Adet', 72)]

Burada görüldüğü gibi “4 Bölmeli Kapaklı Kebap Kabı - 25 Adet” sorgusundan 3 tane %86 dan büyük sonuç dönüyor. Ama benim döngümün olduğu kodda sadece bir adet sonuç var.

csv
Bu da csv dosyamın ekran görüntüsü. Buradan görüldüğü üzere 12. satırda benim sorgum var ve %86 üzeri 2 sonuç bulabilecekken sadece bir tanesini almış ve 13. satırda bir sonraki sorguya geçmiş.

Kodumun son hali ise:

import pandas as pd
from fuzzywuzzy import fuzz
from fuzzywuzzy import process

bizim = pd.read_csv('x_bizim.csv')
karsilastirma = pd.read_csv('x_tumu.csv')

# DataFrame lerden isimleri çıkartma
df1_names = bizim['isim'].values.tolist()
df2_names = list(karsilastirma.isim.unique())

def match_names(name, list_names):
    max_name = ''
    max_score=int()
    for x in list_names:
        score = fuzz.token_sort_ratio(name, x)
        if 86 <= score <= 100:
            max_name = x
            max_score = score

    return (max_name, max_score)


urunler = []
for x in df1_names:
    match = match_names(x, df2_names)
    if match[1] >= 86:
        bizden = str(x)
        eslesen = str(match[0])
        oran = str(match[1])
        urunler.append([bizden, eslesen, oran])

df = pd.DataFrame(urunler,columns = ["bizim","genel","oran"])
df.to_csv('yeni.csv', encoding='utf-8', header=None, mode='a', index=False)

print(df)

Yani bir şekilde bu loop kesiliyor. Bu kesinti benim yanlış şekilde talepte bulunmamdan kaynaklanıyor olabilir, eksik bilgimden kaynaklanıyor olabilir.Doğa üstü olay dışında bir çok sebep sayabiliriz. Bende sonuçta bu işin içinde olan birisi değilim. Bildiğim kadarıyla kendi isteklerimi karşılayan ufak tefek şeyleri kotaracak kadarlık bir yazılım bilgim var. Bu konuda takıldım kaldım ve çözüm üretemiyorum. Eğer csv leri yükleme şansım olsaydı (ki benim bildiğim görsel dosyası dışında bir yükleme yapılmıyor) onları da yüklerdim sonuçta bi kaç kb lik dosyalar ve hiç bir gizli veri içermiyor.

şimd içerideki bir fonksiyon senin for düngünü kıramaz.

  1. senin for döngün zaten değerleri eziyor, onunla ilgili düzeltme önerisini yaptım zaten.
  2. Kullanıdğın kütüphanenin metodu içeride nasıl bir işlem yapıyor bilmiyoruz bununla ilgili bir problemin varsa onun dökümanına bakman gerekiyor. Biz koda göre yorumladığmız için senin kullandığın kütüphane metodu neye göre şeçim yapıyor bilmiyorum.

Burada doğa üstü birşey yok, problem belli döngü kıran birşey de yok işlem içeride belli bir şeye göre seçim yapıyor bunu yanlış buluyorsan o doğrultuda arama yapabilirsin.

1 Beğeni