在数据帧数据上调用函数

时间:2015-06-27 16:33:16

标签: python pandas dataframe function

我不确定我在这里做错了什么,我只是试图用一个if-then-else过滤器调用一个函数并应用于数据帧。

In [7]:
df.dtypes

Out[7]:
Filler     float64
Spot       float64
Strike     float64
cp          object
mid        float64
vol        float64
usedvol    float64
dtype: object

In [8]:
df.head()

Out[8]:
          Filler  Spot  Strike cp  mid   vol  
    0       0.0   100      50  c   0.0   25.0   
    1       0.0   100      50  p   0.0   25.0   
    2       1.0   100      55  c   1.0   24.5  
    3       1.0   100      55  p   1.0   24.5   
    4       2.5   100      60  c   2.5   24.0 

我有以下功能:

def badvert(df):
    if df['vol']>24.5:
        df['vol2'] = df['vol']*2
    else:
        df['vol2'] = df['vol']/2
    return(df['vol2'])

我在这里打电话:

df['vol2']=badvert(df)

生成此错误消息:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-14-bbf7a11a17c9> in <module>()
----> 1 df['vol2']=badvert(df)

<ipython-input-13-6132a4be33ca> in badvert(df)
      1 def badvert(df):
----> 2     if df['vol']>24.5:
      3         df['vol2'] = df['vol']*2
      4     else:
      5         df['vol2'] = df['vol']/2

C:\Users\camcompco\AppData\Roaming\Python\Python34\site-packages\pandas\core\generic.py in __nonzero__(self)
    712         raise ValueError("The truth value of a {0} is ambiguous. "
    713                          "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
--> 714                          .format(self.__class__.__name__))
    715 
    716     __bool__ = __nonzero__

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

我的直觉告诉我这是一个简单的“语法”问题,但我不知所措。任何帮助将不胜感激

2 个答案:

答案 0 :(得分:3)

你希望每行apply,这将使用apply和lambda做你想做的事情:

df["vol2"] = df.apply(lambda row: row['vol'] * 2 if row['vol'] > 24.5 else row['vol'] / 2, axis=1)
print(df)

哪个应输出如下内容:

   Filler  Spot  Strike cp  mid   vol   vol2
0     0.0   100      50  c  0.0  25.0  50.00
1     0.0   100      50  p  0.0  25.0  50.00
2     1.0   100      55  c  1.0  24.5  12.25
3     1.0   100      55  p  1.0  24.0  12.00
4     2.5   100      60  c  2.5  24.0  12.00

或使用您自己的功能:

def badvert(df):
    if df['vol']>24.5:
        df['vol2'] = df['vol']*2
    else:
        df['vol2'] = df['vol']/2
    return df['vol2']
df["vol2"] = df.apply(badvert,axis=1)

axis=0将函数应用于每一列,axis=1将函数应用于每一行。

答案 1 :(得分:2)

df.apply的效果与Python for-loop相当。有时使用apply或for循环逐行计算是不可避免的,但在这种情况下,更快的替代方案是将计算表示为对整列进行的计算。

由于底层数据存储在DataFrame中的方式,并且由于行数通常多于列,因此对整列进行的计算通常比逐行计算更快:

df['vol2'] = np.where(df['vol']>24.5, df['vol']*2, df['vol']/2)