Панды создают столбец на основе значений в другом столбце, который выбран в качестве условия - PullRequest
0 голосов
/ 05 июня 2018

У меня есть следующие df,

id    match_type    amount    negative_amount
1     exact         10        False
1     exact         20        False
1     name          30        False
1     name          40        False
1     amount        15        True
1     amount        15        True 
2     exact         0         False
2     exact         0         False

Я хочу создать столбец 0_amount_sum, который указывает (логическое), если сумма amount равна <= 0 или нет для каждого идентификатораконкретный <code>match_type, например, следующий результат df;

id    match_type    amount    0_amount_sum    negative_amount   
1     exact         10        False           False
1     exact         20        False           False
1     name          30        False           False
1     name          40        False           False
1     amount        15        True            True
1     amount        15        True            True
2     exact         0         True            False
2     exact         0         True            False

для id=1 и match_type=exact, сумма amount равна 30, поэтому 0_amount_sum равно False,Код выглядит следующим образом:

df = df.loc[df.match_type=='exact']

df['0_amount_sum_'] = (df.assign(
    amount_n=df.amount * np.where(df.negative_amount, -1, 1)).groupby(
    'id')['amount_n'].transform(lambda x: sum(x) <= 0))

df = df.loc[df.match_type=='name']

df['0_amount_sum_'] = (df.assign(
    amount_n=df.amount * np.where(df.negative_amount, -1, 1)).groupby(
    'id')['amount_n'].transform(lambda x: sum(x) <= 0))

df = df.loc[df.match_type=='amount']

df['0_amount_sum_'] = (df.assign(
    amount_n=df.amount * np.where(df.negative_amount, -1, 1)).groupby(
    'id')['amount_n'].transform(lambda x: sum(x) <= 0))

Мне интересно, есть ли лучший / более эффективный способ сделать это, особенно когда значения match_type неизвестны, поэтому код может автоматически перечислять всевозможные значения, а затем сделать расчет соответственно.

1 Ответ

0 голосов
/ 05 июня 2018

Мне кажется, нужно groupby по 2 Series (столбцы) вместо фильтрации:

df['0_amount_sum_'] = ((df.amount * np.where(df.negative_amount, -1, 1))
                           .groupby([df['id'], df['match_type']])
                           .transform('sum')
                           .le(0))

   id match_type  amount  negative_amount  0_amount_sum_
0   1      exact      10            False          False
1   1      exact      20            False          False
2   1       name      30            False          False
3   1       name      40            False          False
4   1     amount      15             True           True
5   1     amount      15             True           True
6   2      exact       0            False           True
7   2      exact       0            False           True
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...