যদি কোনও স্ট্রিংয়ের তালিকায় একটি সাবস্ট্রিং থাকে তবে কীভাবে পরীক্ষা করা যায়?


119

কোন ফাংশন যা সংমিশ্রণ সমতুল্য করা হবে df.isin()এবং df[col].str.contains()?

উদাহরণস্বরূপ, বলুন যে আমার কাছে সিরিজ রয়েছে s = pd.Series(['cat','hat','dog','fog','pet'])এবং আমি যেখানে sএমন কোনও জায়গা রয়েছে এমন সমস্ত জায়গাগুলি খুঁজতে চাই ['og', 'at'], আমি 'পোষা প্রাণী' ব্যতীত সমস্ত কিছুই পেতে চাই।

আমার একটি সমাধান আছে, তবে এটি বরং অপ্রয়োজনীয়:

searchfor = ['og', 'at']
found = [s.str.contains(x) for x in searchfor]
result = pd.DataFrame[found]
result.any()

এই কাজ করতে একটি ভাল উপায় আছে কি?


দ্রষ্টব্য : @unutbu দ্বারা বর্ণিত একটি সমাধান রয়েছে যা ব্যবহারের চেয়ে দক্ষ pd.Series.str.contains। পারফরম্যান্স যদি কোনও সমস্যা হয় তবে এটি তদন্তের উপযুক্ত হতে পারে।
জেপিপি

একাধিক কীওয়ার্ড / রেজিক্সগুলি ব্যবহার করে আংশিক স্ট্রিং অনুসন্ধানের জন্য এই উত্তরটি পরীক্ষা করার জন্য উচ্চতর পরামর্শ দিন (" একাধিক সাবস্ট্রিং অনুসন্ধান " সাবহেডিংয়ে স্ক্রোল করুন )।
সিএস 95

উত্তর:


219

একটি বিকল্প হ'ল |আপনার সিরিজের শব্দের প্রতিটি সাবস্ট্রিংয়ের সাথে মিলের চেষ্টা করার জন্যই রেজেক্স অক্ষরটি sব্যবহার করা (এখনও ব্যবহার করা হচ্ছে str.contains)।

আপনি শব্দের যোগদান করে Regex গঠন করা যেতে পারে searchforসঙ্গে |:

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

@ অ্যান্ডি হাইডেন নীচের মন্তব্যে যেমন উল্লেখ করেছেন, আপনার সাবস্ট্রিংগুলিতে যেমন বিশেষ অক্ষর রয়েছে $এবং ^যা আপনি আক্ষরিকভাবে মিলতে চান সেদিকে খেয়াল রাখুন । এই অক্ষরগুলির নিয়মিত অভিব্যক্তিগুলির প্রসঙ্গে নির্দিষ্ট অর্থ রয়েছে এবং এটি মিলাকে প্রভাবিত করবে।

আপনি এইগুলি সহ অ-অক্ষরীয় অক্ষরগুলি এড়িয়ে নিজের সাবস্ট্রিংগুলির তালিকাটিকে আরও নিরাপদ করে তুলতে পারেন re.escape:

>>> import re
>>> matches = ['$money', 'x^y']
>>> safe_matches = [re.escape(m) for m in matches]
>>> safe_matches
['\\$money', 'x\\^y']

এই নতুন তালিকার সাথে থাকা স্ট্রিংগুলি প্রতিটি অক্ষরের সাথে অক্ষরের সাথে মিলিত হবে str.contains



6
আপনার যে জিনিসটি খেয়াল রাখতে হবে তা হ'ল যদি সন্ধানের স্ট্রিংটিতে বিশেষ রেজেক্স অক্ষর থাকে (আপনি পুনরায় পরীক্ষা করে মানচিত্র করতে পারেন )।
অ্যান্ডি হেডেন

@ অ্যান্ডি হাইডেন আপনাকে ধন্যবাদ, আমি এই জটিলতাটি আমলে নেওয়ার জন্য আমার উত্তরটির উন্নতি করেছি।
অ্যালেক্স রিলে

আমি জানি না কেন আপনার পদ্ধতিটি "স্ট্রিংস্টার্টসথথ ('|' .জায়েন (সার্চফোর্ড))" এর সাথে কাজ করে না
ডু হিউন শিন

48

আপনি str.containsএকার ব্যবহার করে একটি রেজেক্স প্যাটার্ন ব্যবহার করতে পারেন OR (|):

s[s.str.contains('og|at')]

অথবা আপনি dataframeতারপরে সিরিজটি যুক্ত করতে পারেন str.contains:

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

আউটপুট:

0 cat
1 hat
2 dog
3 fog 

কীভাবে এটি AND এর জন্য করবেন?
জ্যাকোসোলারি

1
@JacoSolari এই উত্তরটি খুঁজে বার করো stackoverflow.com/questions/37011734/...
জেমস

1
@ জেমস হ্যাঁ, ধন্যবাদ সমাপ্তির জন্য এখানে উত্তরের সর্বাধিক উন্নত অনলাইনার। df.col.str.contains(r'(?=.*apple)(?=.*banana)',regex=True)
জ্যাকোসোলারি

1

এখানে একটি লাইন ল্যাম্বদা এটিও কাজ করে:

df["TrueFalse"] = df['col1'].apply(lambda x: 1 if any(i in x for i in searchfor) else 0)

ইনপুট:

searchfor = ['og', 'at']

df = pd.DataFrame([('cat', 1000.0), ('hat', 2000000.0), ('dog', 1000.0), ('fog', 330000.0),('pet', 330000.0)], columns=['col1', 'col2'])

   col1  col2
0   cat 1000.0
1   hat 2000000.0
2   dog 1000.0
3   fog 330000.0
4   pet 330000.0

লাম্বদা প্রয়োগ করুন:

df["TrueFalse"] = df['col1'].apply(lambda x: 1 if any(i in x for i in searchfor) else 0)

আউটপুট:

    col1    col2        TrueFalse
0   cat     1000.0      1
1   hat     2000000.0   1
2   dog     1000.0      1
3   fog     330000.0    1
4   pet     330000.0    0
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.