اذهب إلى المحتوى
  • 0

دمج عمودين سوياً عن طريق العناصر المتشابهة في pandas

Mohamed Elnemr

السؤال

لدي بيانات في شكل اثنان dataframes كالتالي:

df1 = DataFrame([[10],[20],[30],[40],[50]], index=['one','two','three','four','five'], columns=['number'])

       number
one       10
two       20
three     30
four      40
five      50

df2 = DataFrame([['a'],['b'],['c'],['d'],['e']], index=['two','four','one','three','five'], columns=['letter'])

      letter
two       a
four      b
one       c
three     d
five      e

وأريد انشاء dataframe جديدة تقوم بدمجهم معا عن طريق المقارنة بين ال index وجمع ما هو متشابه سويا بحيث يكون الخرج كالتالي:

      number letter
one         1      a
two         2      b
three       3      c
four        4      d
five        5      e

مع ملاحظة أن العناصر ليست مرتبة سوياً حتى أستطيع دمجهم مباشرة وانما يجب البحث عن التشابهة أولا قبل الدمج. كيف يمكنني فعل هذا؟

تم التعديل في بواسطة Mohamed Elnemr
رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 0

يوجد عدة طرق لتنفيذ المطلوب كما شرح أحمد في التعليق السابق ولكن في بعض الأحيان تحتاج لمكتبة لتسهيل الأمر وإضافة بعض المميزات ويمكنك استخدام المكتبة fuzzymatcher لتنفيذ المطلوب

قم بتثبيتها كالتالي

pip install fuzzymatcher

لاحظ المثال التالي

from fuzzymatcher import link_table, fuzzy_left_join

left_on = ["fname", "mname", "lname",  "dob"]

right_on = ["name", "middlename", "surname", "date"]

fuzzymatcher.link_table(df_left, df_right, left_on, right_on)

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

يمكنك استخدام الدالة get_close_matches للمقارنة بين العناصر وربط العناصر المتشابهة سويا ثم استخدام الدالة join لجمعهم سويا مثل الكود التالي:

In [1]: import difflib 

In [2]: difflib.get_close_matches
Out[3]: <function difflib.get_close_matches>

In [4]: df2.index = df2.index.map(lambda x: difflib.get_close_matches(x, df1.index)[0])

In [5]: df2
Out[5]: 
      letter
one        a
two        b
three      c
four       d
five       e

In [6]: df1.join(df2)
Out[6]: 
       number letter
one        10      a
two        20      b
three      30      c
four       40      d
five       50      e

كذلك يمكنك استخدام الدالة merge اذا كانت الdataframes علي هيئة أعمدة كالتالي:

df1 = DataFrame([[10,'one'],[20,'two'],[30,'three'],[40,'four'],[50,'five']], columns=['number', 'name'])
df2 = DataFrame([['a','one'],['b','two'],['c','three'],['d','four'],['e','five']], columns=['letter', 'name'])

df2['name'] = df2['name'].apply(lambda x: difflib.get_close_matches(x, df1['name'])[0])
df1.merge(df2)

أو استخدام المكتبة fuzzywuzzy لجمعهم سويا كالتالي:

from fuzzywuzzy import fuzz
from fuzzywuzzy import process

fuzzy_merge(df1, df2, 'index', 'index', threshold=80)
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

إضافة للطرق أعلاه.. فلأداء أعلى يفضل استخدام خوارزمية مطابقة السلاسل Jaro-Winkle للقيام بهكذا عمليات، فهي الأفضل من ناحية الأداء والأكثر دقة :


import pandas as pd
import jellyfish
df1 = pd.DataFrame([[1],[2],[3],[4],[5]], index=['one','two','three','four','five'], columns=['number'])
df1
"""
    number
one   	1
two 	  2
three 	3
four 	  4
five 	  5
"""
df2 = pd.DataFrame([['a'],['b'],['c'],['d'],['e']], index=['one','too','three','fours','five'], columns=['letter'])
df2
"""
  letter
one   	a
too   	b
three 	c
fours 	d
five  	e
"""
def get_closest_match(x, list_strings):
  best_match = None
  highest_jw = 0
  for current_string in list_strings:
    current_score = jellyfish.jaro_winkler(x, current_string)
    if(current_score > highest_jw):
      highest_jw = current_score
      best_match = current_string
  return best_match
df2.index = df2.index.map(lambda x: get_closest_match(x, df1.index))
df1.join(df2)
"""
    number 	letter
one   	1 	a
two   	2 	b
three 	3 	c
four 	  4 	d
five 	  5 	e
"""

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...