lookback/shift 在 pandas 数据帧中调用函数

lookback/shift in pandas dataframes calling functions

如果我有以下数据框:

  date       A     B    M     S
 20150101    8     7    7.5   0
 20150101    10    9    9.5   -1
 20150102    9     8    8.5   1
 20150103    11    11   11    0
 20150104    11    10   10.5  0
 20150105    12    10   11    -1
 ...

如果我想通过以下规则创建另一个列'cost':

  1. 如果 S < 0,成本 = (M-B).shift(1)*S
  2. 如果 S > 0,成本 = (M-A).shift(1)*S
  3. 如果 S == 0,成本=0

目前,我正在使用以下功能:

def cost(df):
if df[3]<0:
    return np.roll((df[2]-df[1]),1)*df[3]
elif df[3]>0:
    return np.roll((df[2]-df[0]),1)*df[3]
else:
    return 0
df['cost']=df.apply(cost,axis=0)

还有其他方法吗?我可以以某种方式在用户定义的函数中使用 pandas shift 函数吗?谢谢。

这样做通常很昂贵,因为当您 apply 用户定义函数时,您将失去矢量速度优势。相反,如何使用 the numpy version of the ternary operator:

import numpy as np

np.where(df[3] < 0,
    np.roll((df[2]-df[1]),1),
    np.where(df[3] > 0,
        np.roll((df[2]-df[0]),1)*df[3] 
        0))

(当然赋值给df['cost']).

np.where(condition, A, B) 是 NumPy elementwise 相当于

A if condition else B

np.select(conditions, choices)np.where 的概括,当有两个以上的选择时很有用。

所以,就像 Ami Tavory 的回答一样,除了使用 np.select,你可以使用

import numpy as np
import pandas as pd
df = pd.read_table('data', sep='\s+')
conditions = [S < 0, S > 0]
M, A, B, S = [df[col] for col in 'MABS']
choices = [(M-B).shift(1)*S, (M-A).shift(1)*S]
df['cost'] = np.select(conditions, choices, default=0)

产生

       date   A   B     M  S  cost
0  20150101   8   7   7.5  0   0.0
1  20150101  10   9   9.5 -1  -0.5
2  20150102   9   8   8.5  1  -0.5
3  20150103  11  11  11.0  0   0.0
4  20150104  11  10  10.5  0   0.0
5  20150105  12  10  11.0 -1  -0.5