2017-06-30 58 views
2

的功能。這是我目前的功能:矢量化實施大熊貓

def partnerTransaction(main_df, ptn_code, intent, retail_unique): 

    if intent == 'Frequency': 
     return main_df.query('csp_code == @retail_unique & partner_code == @ptn_code')['tx_amount'].count() 

    elif intent == 'Total_value': 
     return main_df.query('csp_code == @retail_unique & partner_code == @ptn_code')['tx_amount'].sum() 

它所做的是,它接受一個熊貓數據幀(DF 1)和三個搜索參數。 retail_unique是來自另一個數據框(DF 2)的字符串。目前,我使用itertuples遍歷DF 2的行並調用大約200個這樣的函數並寫入第三個DF,這只是一個示例。我在DF 2有大約16000行,所以它非常慢。我想要做的是矢量化這個功能。我希望它能夠返回一個擁有每個零售獨有的tx_amount數量的熊貓系列。所以系列將是

34 # retail a 
54 # retail b 
23 # retail c 

然後,我會映射此係列到第三DF。

有什麼想法可以解決這個問題嗎?

編輯:第一DF包含基於時間數據與每個零售出現多次在一列和另一列的tx_amount,像這樣

Retail tx_amount 
retail_a 50 
retail_b 100 
retail_a 70 
retail_c 20 
retail_a 10 

第二DF被佈置每零售商:

Retail 
retail_a 
retail_b 
retail_c 

回答

1

首先使用mergeleft join

然後groupby通過tx_amount列和聚集由agg功能sizesum一起或單獨在第二溶液中。

reset_index的轉換Series 2列DataFrame

如果既需要一起輸出:

def partnerTransaction_together(df1, df2): 
    df = pd.merge(df1, df2, on='Retail', how='left') 
    d = {'size':'Frequency','sum':'Total_value'} 
    return df.groupby('Retail')['tx_amount'].agg(['size','sum']).rename(columns=d) 

print (partnerTransaction_together(df1, df2)) 
      Frequency Total_value 
Retail       
retail_a   3   130 
retail_b   1   100 
retail_c   1   20 

但如果需要使用條件:

def partnerTransaction(df1, df2, intent): 
    df = pd.merge(df1, df2, on='Retail', how='left') 
    g = df.groupby('Retail')['tx_amount'] 

    if intent == 'Frequency': 
     return g.size().reset_index(name='Frequency') 
    elif intent == 'Total_value': 
     return g.sum().reset_index(name='Total_value') 

print (partnerTransaction(df1, df2, 'Frequency')) 
    Retail Frequency 
0 retail_a   3 
1 retail_b   1 
2 retail_c   1 

print (partnerTransaction(df1, df2, 'Total_value')) 
    Retail Total_value 
0 retail_a   130 
1 retail_b   100 
2 retail_c   20 
+0

你能解釋一下這是如何工作?我是熊貓的新手,我明白你是通過零售將它分組並從中訪問tx_amount系列的。你爲什麼重新設置指數? –

+0

@NeevParikh,jezrael的'agg'解決方案是最好的慣用熊貓。 – piRSquared

1

如果你想要的速度,在這裏是numpy解決方案使用bincount

from collections import OrderedDict 

f, u = pd.factorize(df1.Retail.values) 

c = np.bincount(f) 
s = np.bincount(f, df1.tx_amount.values).astype(df1.tx_amount.dtype) 

pd.DataFrame(OrderedDict(Frequency=c, Total_value=s), u) 

      Frequency Total_value 
retail_a   3   130 
retail_b   1   100 
retail_c   1   20 

定時

df1 = pd.DataFrame(dict(
     Retail=np.random.choice(list('abcdefghijklmnopqrstuvwxyz'), 10000), 
     tx_amount=np.random.randint(1000, size=10000) 
    )) 


%%timeit 
f, u = pd.factorize(df1.Retail.values) 

c = np.bincount(f) 
s = np.bincount(f, df1.tx_amount.values).astype(df1.tx_amount.dtype) 

pd.DataFrame(OrderedDict(Frequency=c, Total_value=s), u) 

1000 loops, best of 3: 607 µs per loop 


%%timeit 
d = {'size':'Frequency','sum':'Total_value'} 
df1.groupby('Retail')['tx_amount'].agg(['size','sum']).rename(columns=d) 

1000 loops, best of 3: 1.53 ms per loop