আমি কীভাবে একটি কলামের স্ট্রিংগুলি থেকে অযাচিত অংশগুলি সরিয়ে দেব?
মূল প্রশ্নটি পোস্ট করার years বছর পরে, পান্ডাসের এখন বেশ কয়েকটি "ভেক্টরাইজড" স্ট্রিং ফাংশন রয়েছে যা পারস্পরিকভাবে এই স্ট্রিং ম্যানিপুলেশন অপারেশনগুলি সম্পাদন করতে পারে।
এই উত্তরটি এই স্ট্রিংয়ের কয়েকটি ফাংশন অন্বেষণ করবে, দ্রুত বিকল্প প্রস্তাব করবে এবং শেষের দিকে একটি সময়ের তুলনায় চলে যাবে।
ম্যাচ করার জন্য স্ট্রিং / প্যাটার্ন এবং এর সাথে প্রতিস্থাপনের জন্য স্ট্রিংগুলি নির্দিষ্ট করুন।
pd.__version__
# '0.24.1'
df
time result
1 09:00 +52A
2 10:00 +62B
3 11:00 +44a
4 12:00 +30b
5 13:00 -110a
df['result'] = df['result'].str.replace(r'\D', '')
df
time result
1 09:00 52
2 10:00 62
3 11:00 44
4 12:00 30
5 13:00 110
আপনার যদি ফলাফলটির পূর্ণসংখ্যায় রূপান্তর করতে হয় তবে আপনি ব্যবহার করতে পারেন Series.astype
,
df['result'] = df['result'].str.replace(r'\D', '').astype(int)
df.dtypes
time object
result int64
dtype: object
আপনি যদি df
জায়গায় স্থান পরিবর্তন করতে না চান তবে ব্যবহার করুন DataFrame.assign
:
df2 = df.assign(result=df['result'].str.replace(r'\D', ''))
df
# Unchanged
আপনি রাখতে চান সাবস্ট্রিংগুলি বের করার জন্য দরকারী Use
df['result'] = df['result'].str.extract(r'(\d+)', expand=False)
df
time result
1 09:00 52
2 10:00 62
3 11:00 44
4 12:00 30
5 13:00 110
এর সাথে extract
, কমপক্ষে একটি ক্যাপচার গ্রুপ নির্দিষ্ট করা প্রয়োজন। expand=False
প্রথম ক্যাপচার গ্রুপ থেকে ধরা পড়া আইটেমগুলির সাথে একটি সিরিজ ফেরত দেবে।
আপনার সমস্ত স্ট্রিং এই ধারাবাহিক কাঠামো অনুসরণ করে ধরে নিয়ে কাজ করে বিভাজন কাজ করে।
# df['result'] = df['result'].str.split(r'\D').str[1]
df['result'] = df['result'].str.split(r'\D').str.get(1)
df
time result
1 09:00 52
2 10:00 62
3 11:00 44
4 12:00 30
5 13:00 110
আপনি যদি কোনও সাধারণ সমাধান খুঁজছেন তবে সুপারিশ করবেন না।
আপনি যদি str
উপরের সংযোগ এবং পঠনযোগ্য অ্যাক্সেসর ভিত্তিক সমাধানগুলি দ্বারা সন্তুষ্ট হন তবে আপনি এখানে থামতে পারেন। তবে আপনি যদি দ্রুত, আরও পারফরম্যান্স বিকল্পে আগ্রহী হন তবে পড়তে থাকুন।
অনুকূলকরণ: তালিকা বিবেচনা
কিছু পরিস্থিতিতে, তালিকা বোঝার জন্য পান্ডাস স্ট্রিং ফাংশনগুলির পক্ষে অনুকূল হওয়া উচিত। কারণটি কারণ স্ট্রিং ফাংশনগুলি ভেক্টরাইজ করা স্বভাবগতভাবে কঠোর (শব্দের সত্যিকার অর্থে), সুতরাং বেশিরভাগ স্ট্রিং এবং রেজেক্স ফাংশনগুলি কেবলমাত্র বেশি ওভারহেডযুক্ত লুপগুলির চারপাশে মোড়ক থাকে।
আমার লেখার জন্য , পান্ডাসে কি লুপগুলি সত্যই খারাপ? আমার কখন যত্ন করা উচিত? , আরও বিশদে যায়।
str.replace
বিকল্প ব্যবহার করে পুনরায় লেখা যেতে পারেre.sub
import re
# Pre-compile your regex pattern for more performance.
p = re.compile(r'\D')
df['result'] = [p.sub('', x) for x in df['result']]
df
time result
1 09:00 52
2 10:00 62
3 11:00 44
4 12:00 30
5 13:00 110
str.extract
উদাহরণ একটি তালিকা ধী ব্যবহার পুনরায় লেখা যেতে পারে re.search
,
p = re.compile(r'\d+')
df['result'] = [p.search(x)[0] for x in df['result']]
df
time result
1 09:00 52
2 10:00 62
3 11:00 44
4 12:00 30
5 13:00 110
যদি এনএএন বা নো-ম্যাচগুলির সম্ভাবনা থাকে তবে কিছু ত্রুটি পরীক্ষার অন্তর্ভুক্ত করতে আপনাকে উপরেরটি পুনরায় লিখতে হবে। আমি এটি একটি ফাংশন ব্যবহার করে করি।
def try_extract(pattern, string):
try:
m = pattern.search(string)
return m.group(0)
except (TypeError, ValueError, AttributeError):
return np.nan
p = re.compile(r'\d+')
df['result'] = [try_extract(p, x) for x in df['result']]
df
time result
1 09:00 52
2 10:00 62
3 11:00 44
4 12:00 30
5 13:00 110
আমরা তালিকা বোধগম্যতা ব্যবহার করে @ ইউমিরো এবং @ মনিবাটারের উত্তরগুলি আবারও লিখতে পারি:
df['result'] = [x.lstrip('+-').rstrip('aAbBcC') for x in df['result']]
এবং,
df['result'] = [x[1:-1] for x in df['result']]
NaN ইত্যাদি পরিচালনা করার জন্য একই বিধি প্রযোজ্য।
পারফরম্যান্স তুলনা
পারফ্লোট ব্যবহার করে উত্পন্ন গ্রাফ । আপনার রেফারেন্সের জন্য সম্পূর্ণ কোড তালিকা। সম্পর্কিত ফাংশন নীচে তালিকাভুক্ত করা হয়।
এগুলির মধ্যে কয়েকটি তুলনা অন্যায্য কারণ তারা ওপির ডেটা কাঠামোর সুবিধা নিয়ে থাকে তবে আপনি যা চান তা থেকে এটি নিয়ে যান। একটি বিষয় লক্ষণীয় যে প্রতিটি তালিকা বোঝার ফাংশন তার সমতুল্য পান্ডাস বৈকল্পিকের চেয়ে দ্রুত বা তুলনীয়।
ক্রিয়াকলাপ
def eumiro(df):
return df.assign(
result=df['result'].map(lambda x: x.lstrip('+-').rstrip('aAbBcC')))
def coder375(df):
return df.assign(
result=df['result'].replace(r'\D', r'', regex=True))
def monkeybutter(df):
return df.assign(result=df['result'].map(lambda x: x[1:-1]))
def wes(df):
return df.assign(result=df['result'].str.lstrip('+-').str.rstrip('aAbBcC'))
def cs1(df):
return df.assign(result=df['result'].str.replace(r'\D', ''))
def cs2_ted(df):
# `str.extract` based solution, similar to @Ted Petrou's. so timing together.
return df.assign(result=df['result'].str.extract(r'(\d+)', expand=False))
def cs1_listcomp(df):
return df.assign(result=[p1.sub('', x) for x in df['result']])
def cs2_listcomp(df):
return df.assign(result=[p2.search(x)[0] for x in df['result']])
def cs_eumiro_listcomp(df):
return df.assign(
result=[x.lstrip('+-').rstrip('aAbBcC') for x in df['result']])
def cs_mb_listcomp(df):
return df.assign(result=[x[1:-1] for x in df['result']])