2017-12-14 65 views
8

में सभी लेकिन एक चरित्र के अंतिम घटना बदलें:पांडा का उपयोग कर तो इस तरह की स्ट्रिंग में सभी लेकिन पिछले अवधि को हटाने के लिए एक dataframe

s = pd.Series(['1.234.5','123.5','2.345.6','678.9']) 
counts = s.str.count('\.') 
target = counts==2 
target 
0  True 
1 False 
2  True 
3 False 
dtype: bool 

s = s[target].str.replace('\.','',1) 
s 
0 1234.5 
2 2345.6 
dtype: object 

मेरी वांछित आउटपुट, हालांकि, यह है:

0 1234.5 
1 123.5 
2 2345.6 
3 678.9 
dtype: object 

मास्क लक्ष्य के साथ प्रतिस्थापन कमांड अनियंत्रित मानों को छोड़ना प्रतीत होता है और मैं यह नहीं देख सकता कि इसका समाधान कैसे किया जाए।

उत्तर

7

विकल्प 1
str.replace साथ इस regex पैटर्न अच्छी तरह से करना चाहिए।

s.str.replace(r'\.(?=.*?\.)', '') 

0 1234.5 
1  123.5 
2 2345.6 
3  678.9 
dtype: object 

विचार यह है कि, जब तक प्रतिस्थापित करने के लिए और अधिक वर्ण हैं, तो प्रतिस्थापित रखें। यहां इस्तेमाल नियमित अभिव्यक्ति के टूटने है -

\.  # '.' 
(?= # positive lookahead 
.*? # match anything 
\.  # look for '.' 
) 

विकल्प 2
आप इस count का उपयोग कर क्या करना चाहते हैं, तो यह असंभव नहीं है, लेकिन यह एक चुनौती है। आप इसे np.vectorize के साथ आसान बना सकते हैं।

def foo(r, c): 
    return r.replace('.', '', c) 

यह vectorize - - सबसे पहले, एक समारोह को परिभाषित

v = np.vectorize(foo) 

अब, समारोह v फोन s गुजर और गिनती को बदलने के लिए -

pd.Series(v(s, s.str.count(r'\.') - 1)) 

0 1234.5 
1  123.5 
2 2345.6 
3  678.9 
dtype: object 

यह है कि मन में रखो मूल रूप से एक गौरवशाली पाश है। इस बात का अजगर बराबर होगा कुछ की तरह -

r = [] 
for x, y in zip(s, s.str.count(r'\.') - 1): 
    r.append(x.replace('.', '', y)) 

pd.Series(r) 

0 1234.5 
1  123.5 
2 2345.6 
3  678.9 
dtype: object 

या, एक सूची समझ का उपयोग कर -

pd.Series([x.replace('.', '', y) for x, y in zip(s, s.str.count(r'\.') - 1)]) 

0 1234.5 
1  123.5 
2 2345.6 
3  678.9 
dtype: object 
+0

तो यह किसी भी अवधि के रूप में लंबे समय के रूप में एक और इसके बारे में आगे मिलान किया जाता है की जगह? मैं 3 मिनट में हाहा स्वीकार कर सकता हूं, आपका बहुत तेज़। – seanysull

+0

एक तरफ से ऐसा किया जा सकता है जिस तरह से मैं कोशिश कर रहा था? – seanysull

+0

@seanysull हम्म, 'प्रतिस्थापन' और regex के साथ? हम्म, जो भी मामला है, आपको यह जानने की जरूरत है कि सामने एक चरित्र है या नहीं, तो लुकहेड से बचा नहीं जा सकता है। –

0

आप नकाबपोश आइटम की जगह और बाकी अछूता रखना चाहते हैं। वास्तव में Series.where करता है, सिवाय इसके कि यह अनमास्क किए गए मानों को प्रतिस्थापित करता है ताकि आपको मुखौटा को अस्वीकार करने की आवश्यकता हो।

s.where(~target, s.str.replace('\.','',1)) 

या आप नकाबपोश मान निर्दिष्ट करके यथा-स्थान परिवर्तन कर सकते हैं, यह शायद सस्ता लेकिन विनाशकारी है।

s[target] = s[target].str.replace('\.','',1) 
संबंधित मुद्दे