Примените функцию к столбцу A, если выполняется условие соответствующего (той же индексной точки) столбца B - PullRequest
2 голосов
/ 23 мая 2019

У меня есть информационный фрейм с информацией о ценах в столбце «закрыть».У меня есть индикаторы в столбцах «КУПИТЬ» и «ПРОДАТЬ», которые являются логическими значениями.Я хотел бы применить функцию к экземпляру в столбце 'close', если и только если выполняется условие для 'BUY', т.е.когда «ПОКУПАТЬ» == 1, применить функцию (возврат за определенный период) к соответствующему значению «закрыть».Я добавил картинку, которая иллюстрирует, что я имею в виду, и показывает фрейм данных.

Спасибо

enter image description here

3233  108.60  0.0   0.0
3234  107.15  0.0   0.0
3235  106.70  0.0   0.0
3236  109.85  0.0   0.0
3237  107.45  0.0   0.0
3238  109.65  0.0   0.0
3239  107.25  0.0   0.0
3240  106.05  0.0   0.0
3241  101.00  0.0   0.0
3242  100.45  0.0   0.0
3243  100.75  0.0   0.0
3244   99.80  0.0   0.0
3245   96.70  0.0   0.0
3246   94.80  0.0   0.0
3247   94.05  0.0   0.0
3248   92.95  0.0   0.0
3249   93.55  0.0   0.0
3250   91.90  0.0   0.0
3251   91.25  1.0   0.0
3252   95.15  0.0   0.0
3253   93.80  0.0   0.0
3254   95.05  0.0   0.0
3255   95.80  0.0   0.0
3256  101.70  0.0   0.0
3257  106.90  0.0   0.0
3258  102.50  0.0   0.0
3259   96.75  0.0   0.0
3260  100.25  0.0   0.0
3261   98.00  0.0   0.0
3262   98.20  0.0   0.0

Ответы [ 2 ]

1 голос
/ 23 мая 2019

Приведенный ниже код получит желаемый доход:

import pandas as pd

data = pd.DataFrame({
        'Index':range(452, 464),
        'close':[113.05,112.05,111.45,114.20,109.45,110.50,109.65,114.4,110.15,110.90,112.25,117.75],
        'BUY':[1,1,0,0,0,0,0,0,0,0,0,0],
        'SELL':[0,0,0,0,0,0,0,0,0,0,0,0]
})

def calculate_buy_returns(data, n):
    returns = []
    for i, row in data.iterrows():
        if row.BUY == 1:
            if  (i + n) < len(data):
                # get the close price at index + n
                close_n = data[data.index == (i + n)].iloc[0].close
                returns.append((close_n - row.close)/row.close)
            else:
                returns.append(0)
        else:
            returns.append(0)
    return returns

data['returns'] = calculate_buy_returns(data, 10)

print(data)

Вывод:

    Index   close  BUY  SELL   returns
0     452  113.05    1     0 -0.007077
1     453  112.05    1     0  0.050870
2     454  111.45    0     0  0.000000
3     455  114.20    0     0  0.000000
4     456  109.45    0     0  0.000000
5     457  110.50    0     0  0.000000
6     458  109.65    0     0  0.000000
7     459  114.40    0     0  0.000000
8     460  110.15    0     0  0.000000
9     461  110.90    0     0  0.000000
10    462  112.25    0     0  0.000000
11    463  117.75    0     0  0.000000
0 голосов
/ 23 мая 2019

Попробуйте DataFrame.apply :

>>> def my_func(s):
...     if s['A']:
...         s['B'] = s['B'] ** 2
...     return s
... 
>>> thing = pd.DataFrame({'A': [True, False, True], 'B': [1, 2, 3]})
>>> thing.apply(my_func, axis=1)
       A   B
0   True   1
1  False   2
2   True  81

Предупреждение: это намного медленнее, чем вы хотели.Он удаляет всю скорость, которую вы получаете от векторизованных вычислений, потому что ваша функция не векторизована.Если следующее, что вы планируете сделать, это извлечь именно эти измененные значения (например, results = thing[thing['A']]['B']), вам следует просто применить свою функцию к mask Series:

>>> thing[thing['A']]['B'] ** 2
0     1
2    81
Name: B, dtype: int64
...