Группировка и агрегирование по нескольким столбцам при применении столбца в качестве аргумента агрегирования в Pandas? - PullRequest
0 голосов
/ 23 февраля 2019

Я пытаюсь сгруппировать ниже DataFrame на основе срока действия и удара.После этого я хотел бы рассчитать разницу между всеми коллами и путами с одинаковыми страйками и датой истечения.В приведенном ниже примере только строки 1 и 2 будут давать результат (15.370001-1.495 =) = 13.875

Как именно я могу продолжить работу без записи цикла for?Я думал о чем-то вроде:

df.groupby(["Expiration","Strike"]).agg(lambda x: x[x.Type == "call"].Price - x[x.Type == "put"].Price + x.Strike)

Однако я не уверен, как передать такие аргументы if (Type equals call) в функцию groupby?

Type       Price Expiration  Strike
0   put  145.000000 2021-01-15   420.0
1  call   15.370001 2018-11-30   262.0
2   put    1.495000 2018-11-30   262.0
3  call   14.930000 2018-11-30   262.5

1 Ответ

0 голосов
/ 23 февраля 2019

Вы можете использовать пользовательскую функцию с помощью GroupBy.apply с next и iter для получения первого значения и, если нет совпадения, получите NaN s:

def f(x):
    c = next(iter(x.loc[x.Type == "call", 'Price']),np.nan)
    p = next(iter(x.loc[x.Type == "put", 'Price']),np.nan) 
    x['new']= c - p + x.Strike
    return x

df = df.groupby(["Expiration","Strike"]).apply(f)
print (df)

   Type       Price  Expiration  Strike         new
0   put  145.000000  2021-01-15   420.0         NaN
1  call   15.370001  2018-11-30   262.0  275.875001
2   put    1.495000  2018-11-30   262.0  275.875001
3  call   14.930000  2018-11-30   262.5         NaN

Другойрешение:

#if possible `call` and `put` are not unique per groups
c = df[df.Type == "call"].groupby(["Expiration","Strike"])['Price'].first()
p = df[df.Type == "put"].groupby(["Expiration","Strike"])['Price'].first()

#if `call` and `put` are unique per groups
#c = df[df.Type == "call"].set_index(["Expiration","Strike"])['Price']
#p = df[df.Type == "put"].set_index(["Expiration","Strike"])['Price']

df1 = df.join((c - p).rename('new'), on=["Expiration","Strike"])
df1['new'] += df1['Strike']
print (df1)
   Type       Price  Expiration  Strike         new
0   put  145.000000  2021-01-15   420.0         NaN
1  call   15.370001  2018-11-30   262.0  275.875001
2   put    1.495000  2018-11-30   262.0  275.875001
3  call   14.930000  2018-11-30   262.5         NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...