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

البحث عن الكلمات التي تحتوى على مقطع substring في pandas

Mohamed Elnemr

السؤال

لدي بيانات على هيئة series في pandas كالتالي:

df = pd.Series(['cat','hat','bat','dog','ant'])

وأود البحث عن الكلمات التي تحتوي علي المقطع "og" والمقطع "at" كيف يمكنني فعل هذا؟

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

Recommended Posts

  • 1

يمكنك ذلك عن طريق str.contains والتي يمكن إستخدامها ل substring search و ايضاً regex based search (والذي يرمز لل regular expression) و هو طريقة البحث by default وقد تأخذ عملية البحث وقت أطول به إذا لم يتم إلغائه في دالة البحث، لاحظ فرق زمن التنفيذ:

import pandas as pd
df = pd.DataFrame({'col':['cat','hat','bat','dog','ant']})
df1 = pd.concat([df] * 1000, ignore_index=True)
%timeit df1[df1['col'].str.contains('og|at')]
%timeit df1[df1['col'].str.contains('og|at', regex=False)]

أو يمكننا إستخدام دالة find في مكتبة numpy :

import numpy as np
import pandas as pd

df = pd.DataFrame({'col':['cat','hat','bat','dog','ant']})
df[np.char.find(df['col'].values.astype(str), 'at') & np.char.find(df['col'].values.astype(str), 'og') > -1]

أو عن طريق دالة query للdf:

df.query('col.str.contains("og|at")', engine='python')

كما يمكن ذلك عن طريق الدالة vectorize في numpy:

import numpy as np
import pandas as pd

df = pd.DataFrame({'col':['cat','hat','bat','dog','ant']})

f = np.vectorize(lambda words, w: w in words)
df[f(df['col'], 'og') | f(df['col'], 'at')]

 

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

  • 1

حسناً إضافة للطرق السابقة إليك طرق إضافية (أنصح بشدة باستخدام vectorize التي ذكرتها @Reem Elmahdiإذا كنت مهتماً بالسرعة):

import pandas as pd
# إنشاء داتا لنعمل عليها
df =pd.DataFrame( {'Name':['Jai', 'Princi', 'Gaurav', 'Anuj'],
        'Age':[27, 24, 22, 32],
        'Address':['Delhi', 'Kanpur', 'Allahabad', 'Kannauj'],
        'Qualification':['Msc', 'MA', 'MCA', 'Phd']})
df
"""
    Name 	Age 	Address 	Qualification
0 	Jai   	27 	  Delhi         	Msc
1 	Princi 	24  	Kanpur          MA
2 	Gaurav 	22  	Allahabad      	MCA
3 	Anuj 	  32 	  Kannauj 	      Phd
"""
# str.find أول طريقة لنستخدم التابع
# a مثلاً نريد البحث عن الأماكن التي توجد بها المحرف
# يعيد هذا التابع الفهرس الأول الذي تواجدت فيه بداية السلسلة الجزئية التي تبحث عنها
sub ='a'
df["Indexes"]= df["Name"].str.find(sub)
df
"""
    Name 	Age 	Address 	Qualification 	Indexes
0 	Jai   	27 	Delhi     	Msc           	1
1 	Princi 	24 	Kanpur 	    MA 	            -1
2 	Gaurav 	22 	Allahabad 	MCA           	1
3 	Anuj 	  32 	Kannauj 	  Phd           	-1
"""
#  findall الطريقة الثانية هي استخدام
#re وذلك من خلال مكتبة 
# هذه الطريقة تمكنك من البحث يطريقة فعالة وسهلة حيث أنك فقط تحدد لها ماتريد البحث عنه 
import re
#ci أو ai هنا نحدد أننا نريد جميع الكلمات التي تحوي 
df['Name'].str.findall('ci|ai', flags=re.IGNORECASE) # هنا قمت بتجاهل حالة الأحرف ويمكنك أن لاتتجاهلها حسبما تريد
# إليك التابع التالي الذي قمت بتعريفه لك بحيث يسهل عليك عملية البحث عن أي سلسلة جزئية وهو حل فعال جداً من ناحية الأداء
#regex وذلك لأنني اعتمدت فيهاستخدام مكتبة التعابير المنتظمة
def stringSearchColumn_DataFrame(df, colName, regex):
    newdf = pd.DataFrame()
    for idx, record in df[colName].iteritems():
        if re.search(regex, record):
            newdf = pd.concat([df[df[colName] == record], newdf], ignore_index=True)
    return newdf
stringSearchColumn_DataFrame(df,"Name","ai")
"""
    Name 	Age 	Address 	Qualification 	Indexes
0 	Jai 	27 	Delhi 	Msc 	1
"""
stringSearchColumn_DataFrame(df,"Name","ai|ci")
"""
    Name   	Age 	Address 	Qualification 	
0 	Princi 	24 	  Kanpur 	  MA 	          
1 	Jai 	  27 	  Delhi 	  Msc 	
"""
# هذا مريح أكثر أليس كذلك؟؟

 

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

  • 0

يمكنك البحث عن طريق عمل list بها المقاطع التى تريد البحث عنها ثم استخدام الدالة searchfor كالتالي:

>>> searchfor = ['og', 'at']
>>> s[s.str.contains('|'.join(searchfor))]
0    cat
1    hat
2    bat
3    dog

كذلك يمكنك استخدام str.contains ووضع المقاطع التي نريد بها مباشرة كالتالي:

>>> df = pd.DataFrame(s)
>>> df[s.str.contains('og|at')] 

0    cat
1    hat
2    bat
3    dog

 

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

  • 0

يمكنك أن تستعمل علامة pipe | مع التابع contains كالتالي:

>>> searchfor = ['og', 'at']
>>> df[df.str.contains('|'.join(searchfor))]
0    cat
1    hat
2    bat
3    dog
dtype: object

أو بدون التابع join كالتالي:

>>> searchfor = ['og', 'at']
>>> df[df.str.contains('og|at')]
0    cat
1    hat
2    bat
3    dog
dtype: object

لكن لاحظ أن النص قد يحتوي على رموز يتم إعتبارها من regex مثل $ و ^ .. إلخ، وبالتالي سوف تؤثر على طريقة البحث، ولحل هذه المشكلة يجب إضافة \\ قبل هذه الرموز، ويمكنك أن تستخدم التابع escape من مكتبة re للقيام بهذه المهمة، كالتالي:

>>> import re
>>> matches = ['$cat', 'dog^ant']
>>> new_matches = [re.escape(m) for m in matches]
>>> new_matches
['\\$cat', 'dog\\^ant']
>>> df = pd.Series(['cat','hat','bat','dog','ant', 'my $cat', 'our dog^ant'])
>>> df[df.str.contains('|'.join(new_matches))]
5        my $cat
6    our dog^ant
dtype: object

 

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

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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...