2017-02-05 5 views
5

मैं निम्नलिखित कोड को वेक्टरकृत तरीके से लिखना चाहता हूं क्योंकि वर्तमान कोड बहुत धीमा है (और पाइथन सर्वोत्तम प्रथाओं को सीखना चाहते हैं)। असल में, कोड यह कह रहा है कि यदि आज का मूल्य कल के मूल्य के 10% के भीतर है, तो आज का मूल्य (एक नए कॉलम में) कल के मूल्य के समान है। अन्यथा, आज के मूल्य में कोई बदलाव नहीं है:लूप का उपयोग करने के बजाय वेक्टरकृत तरीके से कोड कैसे लिखें?

OldCol NewCol 
0  100  100 
1  115  115 
2  101  101 
3  100  101 
4  99  101 
5  70  70 
6  72  70 
7  75  70 
8  78  70 
9  80  70 
10  110  110 

आप कृपया मेरी मदद कर सकते:

def test(df): 
    df['OldCol']=(100,115,101,100,99,70,72,75,78,80,110) 
    df['NewCol']=df['OldCol'] 
    for i in range(1,len(df)-1): 
     if df['OldCol'][i]/df['OldCol'][i-1]>0.9 and df['OldCol'][i]/df['OldCol'][i-1]<1.1: 
      df['NewCol'][i]=df['NewCol'][i-1] 
     else: 
      df['NewCol'][i]=df['OldCol'][i] 
    return df['NewCol'] 

उत्पादन निम्नलिखित होना चाहिए?

मैं कुछ इस तरह उपयोग करना चाहते हैं लेकिन मैं अपने मुद्दे को हल करने के लिए प्रबंधन नहीं किया:

df[(0.9 <= df['NewCol']/df['OldCol']) & (df['NewCol']/df['OldCol'] <= 1.1)] आप सभी पंक्तियों देंगे जहां NewCol है:

def test(df): 
    df['NewCol']=df['OldCol'] 
    cond=np.where((df['OldCol'].shift(1)/df['OldCol']>0.9) & (df['OldCol'].shift(1)/df['OldCol']<1.1)) 
    df['NewCol'][cond[0]]=df['NewCol'][cond[0]-1]  
    return df  
+1

'df' एक डेटा फ्रेम, सही है? 'Df ['OldCol']', या 'NewCol 'का' dtype' क्या है? मुझे लगता है कि यह एक पाइथोनिक की तुलना में एक अच्छा पांडा कोडिंग कोड है। – hpaulj

+0

'' 'OldCol = (100,115,101,100,99,70,72,75,78,80,81,82,110)' '' के लिए वांछित परिणाम क्या है? – wwii

उत्तर

0

आप अपने मूल dataframe मुखौटा बूलियन चाहिए OldCol

के 10% के भीतर तो इन पंक्तियों में NewCol क्षेत्र स्थापित करने के लिए:

within_10 = df[(0.9 <= df['NewCol']/df['OldCol']) & (df['NewCol']/df['OldCol'] <= 1.1)] 
within_10['NewCol'] = within_10['OldCol'] 
0

चूंकि आप अपने आप को "कूद" दिनों को खोजने का एक अच्छा तरीका प्रतीत होता है, इसलिए मैं केवल ट्रिकियर बिट दिखाऊंगा। तो मान लें कि आपके पास old लंबाई N और एक ही आकार के एक बूलियन numpy सरणी jump के साथ एक numpy सरणी है। सम्मेलन के मामले में jump का शून्य तत्व True पर सेट है। तो फिर तुम पहले छलांग के बीच पुनरावृत्ति की संख्या की गणना कर सकते हैं:

jump_indices = np.where(jumps)[0] 
repeats = np.diff(np.r_[jump_indices, [N]]) 

एक बार आप इन आप np.repeat उपयोग कर सकते हैं:

new = np.repeat(old[jump_indices], repeats) 
2

तीन चरणों में एक समाधान:

df['variation']=(df.OldCol/df.OldCol.shift()) 
df['gap']=~df.variation.between(0.9,1.1) 
df['NewCol']=df.OldCol.where(df.gap).fillna(method='ffill') 

के लिए:

OldCol variation gap NewCol 
0  100  nan True  100 
1  115  1.15 True  115 
2  101  0.88 True  101 
3  100  0.99 False  101 
4  99  0.99 False  101 
5  70  0.71 True  70 
6  72  1.03 False  70 
7  75  1.04 False  70 
8  78  1.04 False  70 
9  80  1.03 False  70 
10  110  1.38 True  110 

यह उदाहरण पर लूप की तुलना में 30x तेज लगता है।

एक पंक्ति में:

x=df.OldCol;df['NewCol']=x.where(~(x/x.shift()).between(0.9,1.1)).fillna(method='ffill') 
+0

यह वही है जो मुझे चाहिए - बहुत बहुत धन्यवाद – crazyfrog

संबंधित मुद्दे