मैं किसी स्तंभ में अवांछित भागों को कैसे निकालूं?
मूल प्रश्न पोस्ट किए जाने के 6 साल बाद, पांडा के पास अब "वेक्टराइज्ड" स्ट्रिंग फ़ंक्शन की एक अच्छी संख्या है जो इन स्ट्रिंग हेरफेर संचालन को सफलतापूर्वक कर सकते हैं।
यह उत्तर इनमें से कुछ स्ट्रिंग फ़ंक्शंस का पता लगाएगा, तेज़ विकल्प सुझाएगा, और अंत में तुलनात्मक समय में जाएगा।
मिलान करने के लिए प्रतिस्थापन / प्रतिमान निर्दिष्ट करें, और इसे प्रतिस्थापित करने के लिए प्रतिस्थापन।
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
वह विकल्प जिसे आप रखना चाहते हैं, को निकालने के लिए उपयोगी है।
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
यदि NaN या नो-मैच एक संभावना है, तो आपको कुछ त्रुटि जाँच को शामिल करने के लिए उपरोक्त को फिर से लिखना होगा। मैं एक फ़ंक्शन का उपयोग करके ऐसा करता हूं।
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
सूची संकलन का उपयोग करके हम @ eumiro's और @ MonkeyButter के उत्तरों को फिर से लिख सकते हैं:
df['result'] = [x.lstrip('+-').rstrip('aAbBcC') for x in df['result']]
तथा,
df['result'] = [x[1:-1] for x in df['result']]
NaNs आदि को संभालने के लिए समान नियम लागू होते हैं।
प्रदर्शन तुलना
परफ्लोट का उपयोग करके उत्पन्न रेखांकन । पूर्ण कोड सूची, आपके संदर्भ के लिए। प्रासंगिक कार्य नीचे सूचीबद्ध हैं।
इन तुलनाओं में से कुछ अनुचित हैं क्योंकि वे ओपी के डेटा की संरचना का लाभ उठाते हैं, लेकिन इसमें से आप क्या लेंगे। एक बात ध्यान देने वाली है कि हर लिस्ट कॉम्प्रिहेंशन फंक्शन अपने समकक्ष पांडा वेरिएंट की तुलना में या तो तेज या तुलनीय है।
कार्य
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']])