2014-01-10 3 views
10

Следующее из этого вопроса Python custom function using rolling_apply for pandas, об использовании rolling_apply. Хотя я прогрессировал с моей функции, я изо всех сил, чтобы справиться с функцией, которая требует двух или более столбцов в качестве входов:Python pandas roll_apply ввод двух столбцов в функцию

Создание же настройки, как и прежде

import pandas as pd 
import numpy as np 
import random 

tmp = pd.DataFrame(np.random.randn(2000,2)/10000, 
        index=pd.date_range('2001-01-01',periods=2000), 
        columns=['A','B']) 

Но изменение функции немного взять два колонны.

def gm(df,p): 
    df = pd.DataFrame(df) 
    v =((((df['A']+df['B'])+1).cumprod())-1)*p 
    return v.iloc[-1] 

Это производит следующее сообщение об ошибке:

pd.rolling_apply(tmp,50,lambda x: gm(x,5)) 

    KeyError: u'no item named A' 

Я думаю, что это происходит потому, что вход в лямбда-функции является ndarray длиной 50 и только в первой колонке, и не принимает два столбцы в качестве входных данных. Есть ли способ получить оба столбца в качестве входов и использовать его в функции rolling_apply.

Снова любая помощь будет принята с благодарностью ...

ответ

1

Все rolling_ * Функции работы на 1d массиве. Я уверен, что можно придумать обходные пути для прохождения 2d массивов, но в вашем случае, вы можете просто предвычисление строчном значение для прокатной оценки:

>>> def gm(x,p): 
...  return ((np.cumprod(x) - 1)*p)[-1] 
... 
>>> pd.rolling_apply(tmp['A']+tmp['B']+1, 50, lambda x: gm(x,5)) 
2001-01-01 NaN 
2001-01-02 NaN 
2001-01-03 NaN 
2001-01-04 NaN 
2001-01-05 NaN 
2001-01-06 NaN 
2001-01-07 NaN 
2001-01-08 NaN 
2001-01-09 NaN 
2001-01-10 NaN 
2001-01-11 NaN 
2001-01-12 NaN 
2001-01-13 NaN 
2001-01-14 NaN 
2001-01-15 NaN 
... 
2006-06-09 -0.000062 
2006-06-10 -0.000128 
2006-06-11 0.000185 
2006-06-12 -0.000113 
2006-06-13 -0.000962 
2006-06-14 -0.001248 
2006-06-15 -0.001962 
2006-06-16 -0.003820 
2006-06-17 -0.003412 
2006-06-18 -0.002971 
2006-06-19 -0.003882 
2006-06-20 -0.003546 
2006-06-21 -0.002226 
2006-06-22 -0.002058 
2006-06-23 -0.000553 
Freq: D, Length: 2000 
+0

Спасибо за это, но пример функции 'gm' был просто макет пример .. .so я все еще хочу разобраться, что такое работа, чтобы получить две или более столбцов ... –

1

Вот другая версия этого вопроса: Using rolling_apply on a DataFrame object. Используйте это, если ваша функция возвращает серию.

Поскольку ваш возвращает скаляр, сделайте это.

In [71]: df = pd.DataFrame(np.random.randn(2000,2)/10000, 
        index=pd.date_range('2001-01-01',periods=2000), 
        columns=['A','B']) 

Пересмотрите вашу функцию, чтобы вернуть кортеж с индексом вы хотите использовать и скалярное значение, которое вычисляется. Обратите внимание, что это немного отличается, поскольку мы возвращаем здесь первый индекс (а не нормально возвращенный последним, вы тоже можете это сделать).

In [72]: def gm(df,p): 
       v =((((df['A']+df['B'])+1).cumprod())-1)*p 
       return (df.index[0],v.iloc[-1]) 


In [73]: Series(dict([ gm(df.iloc[i:min((i+1)+50,len(df)-1)],5) for i in xrange(len(df)-50) ])) 

Out[73]: 
2001-01-01 0.000218 
2001-01-02 -0.001048 
2001-01-03 -0.002128 
2001-01-04 -0.003590 
2001-01-05 -0.004636 
2001-01-06 -0.005377 
2001-01-07 -0.004151 
2001-01-08 -0.005155 
2001-01-09 -0.004019 
2001-01-10 -0.004912 
2001-01-11 -0.005447 
2001-01-12 -0.005258 
2001-01-13 -0.004437 
2001-01-14 -0.004207 
2001-01-15 -0.004073 
... 
2006-04-20 -0.006612 
2006-04-21 -0.006299 
2006-04-22 -0.006320 
2006-04-23 -0.005690 
2006-04-24 -0.004316 
2006-04-25 -0.003821 
2006-04-26 -0.005102 
2006-04-27 -0.004760 
2006-04-28 -0.003832 
2006-04-29 -0.004123 
2006-04-30 -0.004241 
2006-05-01 -0.004684 
2006-05-02 -0.002993 
2006-05-03 -0.003938 
2006-05-04 -0.003528 
Length: 1950 
5

Похоже rolling_apply попытается преобразовать ввод пользователя в FUNC ndarray (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.stats.moments.rolling_apply.html?highlight=rolling_apply#pandas.stats.moments.rolling_apply).

Обход основанный на использовании Окс колонке II, который используется для выбора окна внутри манипулирования функцию г:

import pandas as pd 
import numpy as np 
import random 

tmp = pd.DataFrame(np.random.randn(2000,2)/10000, columns=['A','B']) 
tmp['date'] = pd.date_range('2001-01-01',periods=2000) 
tmp['ii'] = range(len(tmp))    

def gm(ii, df, p): 
    x_df = df.iloc[map(int, ii)] 
    #print x_df 
    v =((((x_df['A']+x_df['B'])+1).cumprod())-1)*p 
    #print v 
    return v.iloc[-1] 

#print tmp.head() 
res = pd.rolling_apply(tmp.ii, 50, lambda x: gm(x, tmp, 5)) 
print res 
+0

Это пятно. Мне это нравится. – 8one6

+0

В этом духе, как бы вы могли снять подобный взломать, если индекс был мультииндекс? Или любой не численный индекс, если на то пошло? Всегда необходимо сначала преобразовать индекс в поплавки? – 8one6

+0

Я изменил свой ответ, чтобы он больше не использовал индексы. gm все еще получает массив поплавков, поэтому мне нужно сопоставить их с ints, которые будут использоваться с iloc – lowtech

Смежные вопросы