2013-05-27 63 views
0

以下代碼是使用python 2.7和pandas 0.9.1生成的。熊貓:優化一些python代碼通過擺脫DataFrame.apply()

我有一個數據框有兩列'小'和'主要'。我通過採取兩者的最大絕對值計算「關鍵」的價值,並建立一個名爲「評論家」新列:

>>> import pandas as pd 
>>> df = pd.DataFrame(
...:  {'minor':[-6, -2.3, 19.2], 'major':[2, 3, 7.4]}, 
...:  index=[10,20,30]) 
>>> print df 
    major minor 
10 2.0 -6.0 
20 3.0 -2.3 
30 7.4 19.2 
>>> df['critic'] = df[['minor', 'major']].abs().max(axis=1) 
>>> print df 
    major minor critic 
10 2.0 -6.0  6.0 
20 3.0 -2.3  3.0 
30 7.4 19.2 19.2 

我的問題是建立一個新的專欄,讓說,「critic_vector」顯示專欄的名字誰給了這個價值。到現在爲止,我使用DataFrame.apply()是這樣的:

>>> def get_col_name(row, df, headers): 
     tmp = (abs(df[headers].ix[row.name]) == row['critic']) 
     retval = tmp.index[tmp.argmax()] 
     return retval 
>>> df['critic_vector'] = df.apply(get_col_name, 
            axis=1, 
            args=(df ,['minor', 'major'])) 
>>>print df 
    major minor critic critic_vector 
10 2.0 -6.0  6.0  minor 
20 3.0 -2.3  3.0  major 
30 7.4 19.2 19.2  minor 

它正常工作;然而,使用大量的數據,df.apply()函數是我的第一個瓶頸。有沒有辦法直接做到這一點,而不使用df.apply()?

在此先感謝

回答

0

隨想:拿到指標,你可以使用.idxmax代替max,即

>>> w = df[['minor','major']].abs().idxmax(axis=1) 
>>> w 
10 minor 
20 major 
30 minor 
dtype: object 

,然後你可以使用lookup(有可能是簡單的東西,但我M右現在缺的話):

>>> df.lookup(df.index, w) 
array([ -6. , 3. , 19.2]) 

督察:

>>> df['critic_vector'] = df[['minor','major']].abs().idxmax(axis=1) 
>>> df['critic'] = abs(df.lookup(df.index, df.critic_vector)) 
>>> df 
    major minor critic_vector critic 
10 2.0 -6.0   minor  6.0 
20 3.0 -2.3   major  3.0 
30 7.4 19.2   minor 19.2 

我不是超滿意的lookup行 - 你可以用你原來max調用替換它,當然 - 但我認爲idxmax的做法是不壞的一個。

+0

酷!我採用「lookup」方法: In [8]:%timeit df ['r'] = df [['minor','major']]。abs().max(axis = 1) 1000循環,最好是每個循環3:405 us In [9]:%timeit df ['critics'] = abs(df.lookup(df.index,df.critic_vector)) 10000循環,最好是3:每個循環118美元 – Nic