有趣的是Pandas`rolling_apply`和TypeError

时间:2014-08-23 07:40:06

标签: python pandas

我真的在与熊猫rolling_apply function挣扎。我尝试将过滤器应用于下面的某些时间序列数据,并为异常值制作新系列。当值为异常值时,我希望值返回True

ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))

window, alpha, gamma = 60, .05, .03

def trim_moments(arr, alpha):
    np.sort(arr)
    n = len(arr)
    k = int(round(n*float(alpha))/2)
    return np.mean(arr[k+1:n-k]), np.std(arr[k+1:n-k])

# First function that tests whether criteria is met.
def bg_test(arr,alpha,gamma):
    local_mean, local_std = trim_moments(arr, alpha)
    return np.abs(arr - local_mean) < 3 * local_std + gamma

这是我运行的功能

outliers = pd.rolling_apply(ts, window, bg_test, args=(alpha,gamma))

返回错误:

TypeError: only length-1 arrays can be converted to Python scalars

我的故障排除表明问题出在布尔返回语句中。当我简化函数并使用np.mean/std而不是我自己的函数时,我不断收到类似的错误。似乎TypeError的先前问题是由于在Numpy Arrays上执行非向量化操作,但这似乎不是问题所在。

我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

这不是一个有用的消息,但我相信错误正在发生,因为rolling_apply目前需要一个类似的类型返回数组(甚至可能必须是浮点数)。但是,如果你将三个操作(均值,标准,异常逻辑)分解为步骤,它应该可以正常工作。

ts.name = 'value'

df = pd.DataFrame(ts)

def trimmed_apply(arr, alpha, f):
    np.sort(arr)
    n = len(arr)
    k = int(round(n*float(alpha))/2)
    return f(arr[k+1:n-k])

df['trimmed_mean'] = pd.rolling_apply(df['value'], window, trimmed_apply, args=(alpha, np.mean))
df['trimmed_std'] = pd.rolling_apply(df['value'], window, trimmed_apply, args=(alpha, np.std))

df['outlier'] = np.abs(arr - df['trimmed_mean']) < 3 *  df['trimmed_std'] + gamma