360

我使用 Pandas 作为数据库替代品,因为我有多个数据库(OracleSQL Server等),并且我无法将命令序列转换为 SQL 等价物。

我在 DataFrame 中加载了一个表,其中包含一些列:

YEARMONTH, CLIENTCODE, SIZE, etc., etc.

在 SQL 中,计算每年不同客户的数量是:

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

结果将是

201301    5000
201302    13245

我怎样才能在熊猫中做到这一点?

4

10 回答 10

536

我相信这就是你想要的:

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
于 2013-03-14T14:09:06.103 回答
123

这是另一种方法,它更简单。假设您的数据框名称是daat,列名称是YEARMONTH

daat.YEARMONTH.value_counts()
于 2017-07-02T11:16:54.497 回答
52

有趣的是,通常len(unique())nunique().

于 2014-05-05T02:59:28.173 回答
17

我也在使用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
于 2019-08-01T09:38:19.670 回答
9

列的不同以及其他列上的聚合

要获取任何列的不同数量的值(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)
于 2020-04-20T10:47:51.150 回答
5

使用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
于 2018-11-23T15:16:20.597 回答
1

这是一种在多列上计数不同的方法。让我们有一些数据:

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
于 2020-02-03T00:40:45.490 回答
1

创建一个数据透视表并使用nunique series 函数:

ID = [ 123, 123, 123, 456, 456, 456, 456, 789, 789]
domain = ['vk.com', 'vk.com', 'twitter.com', 'vk.com', 'facebook.com',
          'vk.com', 'google.com', 'twitter.com', 'vk.com']
df = pd.DataFrame({'id':ID, 'domain':domain})
fp = pd.pivot_table(data=df, index='domain', aggfunc=pd.Series.nunique)
print(fp)

输出:

               id
domain
facebook.com   1
google.com     1
twitter.com    2
vk.com         3
于 2021-06-28T14:15:31.853 回答
0

使用新的 Pandas 版本,很容易得到一个数据框:

unique_count = pd.groupby(['YEARMONTH'], as_index=False).agg(uniq_CLIENTCODE=('CLIENTCODE', pd.Series.count))
于 2019-10-02T14:58:40.960 回答
0

现在您还可以使用dplyrPython 中的语法来执行此操作:

>>> from datar.all import f, tibble, group_by, summarise, n_distinct
>>>
>>> data = tibble(
...     CLIENT_CODE=[1,1,2,1,2,2,3],
...     YEAR_MONTH=[201301,201301,201301,201302,201302,201302,201302]
... )
>>>
>>> data >> group_by(f.YEAR_MONTH) >> summarise(n=n_distinct(f.CLIENT_CODE))
   YEAR_MONTH       n
      <int64> <int64>
0      201301       2
1      201302       3
于 2021-06-17T02:16:17.507 回答