Подсчитайте количество уникальных значений в группе - PullRequest
0 голосов
/ 10 мая 2018

У меня есть 2 столбца - _a, _b.

import numpy as np 
import pandas as pd
df = pd.DataFrame({'_a':[1,1,1,2,2,3,3],'_b':[3,4,5,3,3,3,9], 'a_b_3':[3,3,3,1,1,2,2]})
df

    _a  _b  a_b_3   
0   1   3   3
1   1   4   3
2   1   5   3
3   2   3   1
4   2   3   1
5   3   3   2
6   3   9   2

Мне нужно создать столбец a_b_3 (уникальный счетчик из столбца '_b'), использовать groupby из панд. Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 10 мая 2018

Похоже, вы хотите transform + nunique;

df['a_b_3'] = df.groupby('_a')['_b'].transform('nunique')        
df
   _a  _b  a_b_3
0   1   3      3
1   1   4      3
2   1   5      3
3   2   3      1
4   2   3      1
5   3   3      2
6   3   9      2

Это эффективно groupby + nunique + map:

v = df.groupby('_a')['_b'].nunique()
df['a_b_3'] = df['_a'].map(v)

df
   _a  _b  a_b_3
0   1   3      3
1   1   4      3
2   1   5      3
3   2   3      1
4   2   3      1
5   3   3      2
6   3   9      2
0 голосов
/ 10 мая 2018

Если я правильно понимаю, что вы хотите сгруппировать по столбцу _a, подсчитайте количество уникальных значений в столбце _b в каждой группе, а затем добавьте этот счетчик к исходному кадру данных, используя _a в качестве ключа.Следующий код должен достичь этого.

df.merge(pd.DataFrame(df.groupby('_a')._b.nunique()), left_on='_a', right_index=True)

Если разбить его, сначала нужно сгруппировать по _a, а затем сосчитать уникальные значения в столбце _b.Вот что делает df.groupby('_a')._b.nunique().Затем он объединяется с исходным кадром данных с использованием _a в качестве ключа.Groupby возвращает серию, поэтому нам нужно преобразовать ее в кадр данных перед объединением, следовательно, ответ pd.DataFrame.

EDIT

@ COLDSPEED выше гораздо эффективнее, чем этот.Чтобы дать представление о разнице в скорости, я запустил timeit, которое показывает увеличение скорости в 2 раза на этом небольшом кадре данных, на больших кадрах данных, вероятно, будет еще больше.

Использование слияния:

%timeit df.merge(pd.DataFrame(df.groupby('_a')._b.nunique()), left_on='_a', right_index=True)
1.43 ms ± 74.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Использование преобразования:

%timeit df.groupby('_a')['_b'].transform('nunique')
750 µs ± 32 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
0 голосов
/ 10 мая 2018

Использование -

df2=df.groupby(['_a'])['_b'].nunique().reset_index()
df['a_b_3'] = df.merge(df2, how='left', on='_a')[['_b_y']]

выход

   _a  _b  a_b_3
0   1   3      3
1   1   4      3
2   1   5      3
3   2   3      1
4   2   3      1
5   3   3      2
6   3   9      2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...