Как использовать groupby для одного столбца и выполнять сравнения для нескольких столбцов в Pandas? - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть данные о пользователях, независимо от того, зарегистрировались они или нет, и прогноз модели относительно того, зарегистрировались они или нет.Я хочу найти для каждого пользователя: TP (они зарегистрировались, и модель предсказала, что они сделали), FP (они не зарегистрировались, но модель предсказала, что они сделали), FN (они зарегистрировались, но модель не предсказала нет), иTN (они не подписались, и модель предсказала нет).Здесь 1 означает, что они зарегистрировались, а 0 - нет.Я хочу группировать пользователей, а затем выполнять сравнения, используя два других столбца.Например, у меня может быть что-то вроде следующего:

Users    |    Signed_up    |     Prediction   |
User1         1                  0            
User2         0                  0
User1         1                  1
User3         1                  1
User2         0                  1
User2         0                  0
...

For TP, the resulting table might look something like:

Users    |    TP    |
User1         1
User2         0
User3         1

For TN, the resulting table might look something like:
Users    |    TN    |
User1         0
User2         1
User3         0

and so on for FP and FN.

Я предполагаю, что я группирую по столбцу Users и использую лямбда-функцию для сравнения столбцов Sign_up и Prediction, но яЯ не уверен, как на самом деле это сделать.Буду признателен за любую помощь!

Ответы [ 3 ]

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

Сделайте сравнение перед вами groupby, а затем groupby + sum

(df.assign(TP = df.Signed_up & df.Prediction, 
           TN = (df.Signed_up == 0) & (df.Prediction == 0),
           FN = df.Signed_up & (df.Prediction == 0), 
           FP = (df.Signed_up == 0) & df.Prediction)
   .groupby('Users')['TP', 'TN', 'FN', 'FP'].sum())

       TP   TN   FN   FP
Users                   
User1   1  0.0  1.0  0.0
User2   0  2.0  0.0  1.0
User3   1  0.0  0.0  0.0

Вдохновленный @BrianJoseph, с гораздо меньшим набором текста, вы можете groupby все 3 столбцаопределите размер и распакуйте все, кроме пользователей:

df.groupby([*df]).size().unstack([1,2]).fillna(0)

Signed_up     1         0     
Prediction    0    1    0    1
Users                         
User1       1.0  1.0  0.0  0.0
User2       0.0  0.0  2.0  1.0
User3       0.0  1.0  0.0  0.0
0 голосов
/ 10 декабря 2018

Помните, что панды могут группироваться, используя результаты функции.Чтобы различать эти 4 класса результатов, вам просто нужно знать отношения между Signed_up и Prediction.Вы можете классифицировать их следующим образом:

grps = df.groupby(lambda index: (df.loc[index, 'Signed_up'], df.loc[index, 'Prediction']))

Это просто дает вам объект groupby, и вы можете свободно называть группы как:

tp_df = grps.get_group((1,1))
0 голосов
/ 10 декабря 2018

Если вы создаете разные dfs для каждого предсказания модели, которое выглядит из вашего поста, вы можете сделать это, используя логическое маскирование и побитовый оператор &.& означает, что для возврата значения должны быть выполнены оба условия, поэтому:

df = pd.read_csv('./Desktop/models.csv')

TP = df.loc[(df['Signed_up'] == 1) & (df['Prediction'] == 1)]

TN = df.loc[(df['Signed_up'] == 0) & (df['Prediction'] == 0)]

FN = df.loc[(df['Signed_up'] == 1) & (df['Prediction'] == 0)]

FP = df.loc[(df['Signed_up'] == 0) & (df['Prediction'] == 1)]

output:

>>> TP
   Users  Signed_up  Prediction
2  User1          1           1
3  User3          1           1
>>> TN = df.loc[(df['Signed_up'] == 0) & (df['Prediction'] == 0)]
>>> TN
   Users  Signed_up  Prediction
1  User2          0           0
5  User2          0           0
>>> FN = df.loc[(df['Signed_up'] == 1) & (df['Prediction'] == 0)]
>>> FN
   Users  Signed_up  Prediction
0  User1          1           0
>>> FP = df.loc[(df['Signed_up'] == 0) & (df['Prediction'] == 1)]
>>> FP
   Users  Signed_up  Prediction
4  User2          0           1
...