为什么dataframe.appy花费太多时间

时间:2016-11-05 04:50:12

标签: python pandas dataframe

我有一个数据框'df_ret_temp'

enter image description here

enter image description here 我想设置列accMonth值。 有快速运行的代码

df_ret_temp.loc[df_ret_temp['tradeDate'].str[5:7]<='03','accMonth']=df_ret_temp['tradeDate'].str[0:4].apply(lambda x:str(int(x)-1))+'12'
df_ret_temp.loc[(df_ret_temp['tradeDate'].str[5:7]<='06') &
                (df_ret_temp['tradeDate'].str[5:7]>'03'),'accMonth']=df_ret_temp['tradeDate'].str[0:4]+'03'

df_ret_temp.loc[(df_ret_temp['tradeDate'].str[5:7]<='09') &
                (df_ret_temp['tradeDate'].str[5:7]>'06'),'accMonth']=df_ret_temp['tradeDate'].str[0:4]+'06'

df_ret_temp.loc[(df_ret_temp['tradeDate'].str[5:7]<='12') &
                (df_ret_temp['tradeDate'].str[5:7]>'09'),'accMonth']=df_ret_temp['tradeDate'].str[0:4]+'09'

但是,当我使用apply函数设置列accMonth值时。代码花费的时间太长。

def df_ret_tempFun(row):
    if row['tradeDate'][5:7]<='03':
        row['accMonth']=str(int(row['tradeDate'][0:4])-1)+'12'
    elif row['tradeDate'][5:7]<='06' and row['tradeDate'][5:7]>'03':
        row['accMonth']=row['tradeDate'][0:4]+'03'
    elif row['tradeDate'][5:7]<='09' and row['tradeDate'][5:7]>'06':
        row['accMonth']=row['tradeDate'][0:4]+'06'
    else:
         row['accMonth']=row['tradeDate'][0:4]+'09'
    return row
df_ret_temp=df_ret_temp.apply(df_ret_tempFun,axis=1)

为什么apply函数的性能较低。

1 个答案:

答案 0 :(得分:2)

.apply(..., axis=1)是一个for x in df.iter*循环,所以它没有矢量化,因此非常慢。

但你的问题是XY problem

的一个很好的例子

这是你的“未被问及”的熊猫解决方案;-)问题:

In [33]: x
Out[33]:
         Date
0  2007-01-01
1  2007-04-02
2  2007-08-03
3  2007-11-04

In [34]: x.dtypes
Out[34]:
Date    object
dtype: object

首先确保您的Date列属于datetime dtype:

In [35]: x.Date = pd.to_datetime(x.Date)

In [36]: x.dtypes
Out[36]:
Date    datetime64[ns]
dtype: object

矢量化解决方案:

In [37]: x['accMonth'] = pd.PeriodIndex(pd.PeriodIndex(df.Date, freq='Q') - 1, freq='3M')

In [38]: x
Out[38]:
        Date accMonth
0 2007-01-01  2006-12
1 2007-04-02  2007-03
2 2007-08-03  2007-06
3 2007-11-04  2007-09