Количество появлений значений для каждой группы в виде отдельных столбцов - PullRequest
0 голосов
/ 25 декабря 2018

У меня есть таблица, которая имеет около 31 миллиона записей.Существует около 10 столбцов, два из которых - номер карты и транзакция_стата.Каждая карточка может иметь несколько рядов.таким образом, может быть 2000 строк одной и той же карты, причем каждая строка в качестве транзакции с соответствующим статусом

action_Status имеет значение «Y» / «N».

я хочу добавить еще две колонки к этой таблице: «count_of_approved», «count_of_rejected» с использованием pandas dataframe.

Как мне это сделать?До сих пор я использовал get_dummies () и merge (), однако это занимает много времени и хуже, приводит к ошибке нехватки памяти.

так что мой ввод такой, как показано ниже:

trn_id | card_id | status
1      | c1      | Y
2      | c2      | Y
3      | c2      | N
4      | c3      | Y 
5      | c3      | Y 

я хотел бы, чтобы мой вывод был

trn_id | card_id | status | num_approved | num_of_denied
1      | c1      | Y      | 1            | 0
2      | c2      | Y      | 1            | 1
3      | c2      | N      | 1            | 1
4      | c3      | Y      | 2            | 0
5      | c3      | Y      | 2            | 0

мой код, указанный ниже:

import pandas as panda
a = panda.DataFrame({'id':[1,2,3],'c_id':[22,22,33], 'status':['Y','Y','N']})
temp = a.status.str.get_dummies()
a[['N','Y']]= temp
tt = a.groupby(['c_id'])['Y'].count()
tt=tt.reset_index()
yes_count_added = a.merge(tt,how='right',on='c_id')
yes_count_added.rename(columns = {'Y_y':'num_of_approved'})

Ответы [ 3 ]

0 голосов
/ 25 декабря 2018

Используйте str.get_dummies + один groupby вызов для исполнения:

df.status.str.get_dummies().groupby(df.card_id).transform('sum')

   N  Y
0  0  1
1  1  1
2  1  1
3  0  2
4  0  2

v = (df.status
       .str.get_dummies()
       .groupby(df.card_id)
       .transform('sum')
       .rename({'Y': 'num_approved', 'N': 'num_denied'}, axis=1))

pd.concat([df, v], axis=1)

   trn_id card_id status  num_denied  num_approved
0       1      c1      Y           0             1
1       2      c2      Y           1             1
2       3      c2      N           1             1
3       4      c3      Y           0             2
4       5      c3      Y           0             2
0 голосов
/ 25 декабря 2018

Вы можете использовать кросс-таблица :

import pandas as pd

a = pd.DataFrame(
    {'trn_id': [1, 2, 3, 4, 5],
     'card_id': ['c1', 'c2', 'c2', 'c3', 'c3'],
     'status': ['Y', 'Y', 'N', 'Y', 'Y']})

crosstab = pd.crosstab(a.card_id, a.status).reset_index(level=0).rename(
    columns={'Y': 'num_approved', 'N': 'num_denied'})
print(pd.merge(a, crosstab, on='card_id'))

Выход

  card_id status  trn_id  num_denied  num_approved
0      c1      Y       1           0             1
1      c2      Y       2           1             1
2      c2      N       3           1             1
3      c3      Y       4           0             2
4      c3      Y       5           0             2
0 голосов
/ 25 декабря 2018

Вы можете GroupBy card_id и использовать transform с лямбда-выражением равным sum количество раз, status равное Y дляnum_approved или N для num_of_denied с использованием eq:

df['num_approved'] = df.groupby('card_id').status.transform(
                                lambda x: x.eq('Y').sum())
df['num_of_denied'] = df.groupby('card_id').status.transform(
                                 lambda x: x.eq('N').sum())

     trn_id card_id  status    num_approved    num_of_denied
0       1      c1      Y             1              0
1       2      c2      Y             1              1
2       3      c2      N             1              1
3       4      c3      Y             2              0
4       5      c3      Y             2              0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...