Количество панд (отличный) эквивалент


289

Я использую панд в качестве заменителя БД, так как у меня есть несколько баз данных (oracle, mssql и т. Д.), И я не могу сделать последовательность команд в эквиваленте SQL.

У меня есть таблица, загруженная в DataFrame с несколькими столбцами:

YEARMONTH, CLIENTCODE, SIZE, .... etc etc

В SQL для подсчета количества разных клиентов в год было бы:

SELECT count(distinct CLIENTCODE) FROM table GROUP BY YEARMONTH;

И результат будет

201301    5000
201302    13245

Как я могу сделать это в пандах?


Я сделал table.groupby (['YEARMONTH']) ['CLIENTCODE']. Unique () и пришел с двумя сериями, проиндексированными YEARMONTH и со всеми уникальными значениями. Как посчитать количество значений по каждой серии?
Адриано Алмейда

Для некоторых value_countsможет быть ответ, который вы ищете: pandas.pydata.org/pandas-docs/stable/generated/…
sachinruk

Ответы:


434

Я считаю, что это то, что вы хотите:

table.groupby('YEARMONTH').CLIENTCODE.nunique()

Пример:

In [2]: table
Out[2]: 
   CLIENTCODE  YEARMONTH
0           1     201301
1           1     201301
2           2     201301
3           1     201302
4           2     201302
5           2     201302
6           3     201302

In [3]: table.groupby('YEARMONTH').CLIENTCODE.nunique()
Out[3]: 
YEARMONTH
201301       2
201302       3

2
Что если у меня есть несколько столбцов, которые я хочу, чтобы они были уникальными вместе, как в .drop_duplicates (subset = ['col1', 'col2'])?
ErnestScribbler

4
Как получить доступ к этому уникальному количеству. Как нет названия столбца
Тарун Ханэя

Большое спасибо, я использовал этот стиль на выходе resample. df_watch_record.resample ('M'). user.nunique () подсчитывает количество уникальных пользователей, которые смотрели фильм в месяц.
Мехди Каземи

1
и сортируйте их с помощью table.groupby ('YEARMONTH'). CLIENTCODE.nunique (). sort_values ​​(ascending = False)
wllbll

Можно ли получить идентификатор группы после nunique? Попробуйте, как я мог, я не могу найти способ, так как результатом этого ответа является, а Seriesне а DataFrame.
Джош Хансен

93

Вот еще один метод, очень простой, скажем, имя вашего фрейма данных и имя daatстолбцаYEARMONTH

daat.YEARMONTH.value_counts()

1
Мне нравится этот ответ. Как я могу использовать этот метод, если имя моего столбца имеет «.» в нем (например, 'ck.Class')? Спасибо

5
daat ['ck.Class']. value_counts ()
StatguyUser

28
Это не относится к заданному вопросу.
Аарон Шумахер

6
это подсчет количества наблюдений в каждой группе, а не уникальное значение определенного столбца в каждой группе.
Джейсон Гол

2
Это неправильный ответ; это не отражает DISTINCTтребование из вопроса! Кроме того, он не включает в себя количество NaN!
Кори Левинсон

47

Интересно, что очень часто len(unique())это в несколько раз (3x-15x) быстрее, чем nunique().


11
Вы имеете в виду это? .CLIENTCODE.apply(lambda x: len(x.unique())), От здесь
user4015990

6
@ user32185 тебе нужно было бы перевести его на applyзвонок с лямбдой. Так , например, df.groupby('YEARMONTH')['CLIENTCODE'].apply(lambda x: x.unique().shape[0]).
3новак,

3
Синтаксис не совсем понятен, я не использовал len(df['column'].unique())лямбда-функции
mlh351

Я получил TypeError: object of type 'method' has no len()от Chen'sкомментариев, 3novak'sработал на меня.
Джейсон Гол

4

Используя crosstab, это вернет больше информации, чемgroupby nunique

pd.crosstab(df.YEARMONTH,df.CLIENTCODE)
Out[196]: 
CLIENTCODE  1  2  3
YEARMONTH          
201301      2  1  0
201302      1  2  1

После небольшого изменения выведите результат

pd.crosstab(df.YEARMONTH,df.CLIENTCODE).ne(0).sum(1)
Out[197]: 
YEARMONTH
201301    2
201302    3
dtype: int64

Как я могу экспортировать это как две колонки YEARMONTHи count. Также я могу установить количество в порядке убывания?
Муртаза Хаджи

3

Я также использую, nuniqueно это будет очень полезно, если вам нужно использовать агрегатную функцию, как 'min', 'max', 'count' or 'mean'и т. Д.

df.groupby('YEARMONTH')['CLIENTCODE'].transform('nunique') #count(distinct)
df.groupby('YEARMONTH')['CLIENTCODE'].transform('min')     #min
df.groupby('YEARMONTH')['CLIENTCODE'].transform('max')     #max
df.groupby('YEARMONTH')['CLIENTCODE'].transform('mean')    #average
df.groupby('YEARMONTH')['CLIENTCODE'].transform('count')   #count

1

Различный столбец наряду с агрегациями на других столбцах

Чтобы получить различное количество значений для любого столбца ( CLIENTCODEв вашем случае), мы можем использовать nunique. Мы можем передать входные данные в виде словаря в aggфункции вместе с агрегатами в других столбцах:

grp_df = df.groupby('YEARMONTH').agg({'CLIENTCODE': ['nunique'],
                                      'other_col_1': ['sum', 'count']})

# to flatten the multi-level columns
grp_df.columns = ["_".join(col).strip() for col in grp_df.columns.values]

# if you wish to reset the index
grp_df.reset_index(inplace=True)

0

С новой версией панд легко получить в качестве датафрейма

unique_count = pd.groupby(['YEARMONTH'], as_index=False).agg(uniq_CLIENTCODE =('CLIENTCODE',pd.Series.count))

0

Здесь есть подход, позволяющий рассчитывать несколько столбцов. Давайте иметь некоторые данные:

data = {'CLIENT_CODE':[1,1,2,1,2,2,3],
        'YEAR_MONTH':[201301,201301,201301,201302,201302,201302,201302],
        'PRODUCT_CODE': [100,150,220,400,50,80,100]
       }
table = pd.DataFrame(data)
table

CLIENT_CODE YEAR_MONTH  PRODUCT_CODE
0   1       201301      100
1   1       201301      150
2   2       201301      220
3   1       201302      400
4   2       201302      50
5   2       201302      80
6   3       201302      100

Теперь перечислите интересующие вас столбцы и используйте groupby в слегка измененном синтаксисе:

columns = ['YEAR_MONTH', 'PRODUCT_CODE']
table[columns].groupby(table['CLIENT_CODE']).nunique()

Мы получаем:

YEAR_MONTH  PRODUCT_CODE CLIENT_CODE        
1           2            3
2           2            3
3           1            1
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.