等效的熊猫数(不同)


288

我使用pandas作为数据库替代品,因为我有多个数据库(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/genic / ...
sachinruk

Answers:


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
如何访问此唯一计数。由于没有列名
塔伦·哈内贾

非常感谢,我在重采样输出中使用了这种样式。df_watch_record.resample('M')。user.nunique()计算每月观看电影的唯一身份用户数。
Mehdi Kazemi '18年

1
并使用table.groupby('YEARMONTH')。CLIENTCODE.nunique()。sort_values(ascending = False)进行
排序

之后是否可以检索组标识符nunique?尽我所能,我无法找到办法,因为此答案的结果是a Series,而不是a DataFrame
乔什·汉森

92

这是另一种方法,非常简单,可以说您的数据框名称为daat,列名称为YEARMONTH

daat.YEARMONTH.value_counts()

1
我喜欢这个答案。如果我的列名带有“。”,如何使用此方法?在其中(例如“ ck.Class”)?谢谢

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

27
这不能解决所问的问题。
亚伦·舒马赫

6
这是对每组中观察值的计数,而不是每组中某列的唯一值。
杰森目标

2
这是错误的答案;它不能反映问题的DISTINCT要求!而且,它不包括NaN
科里·莱文森

47

有趣的是,通常len(unique())速度比快几倍(3x-15x)nunique()


11
你是这个意思?.CLIENTCODE.apply(lambda x: len(x.unique())),从这里开始
user4015990 2015年

6
@ user32185,您必须将其放入apply带有lambda 的呼叫中。例如,df.groupby('YEARMONTH')['CLIENTCODE'].apply(lambda x: x.unique().shape[0])
3novak

3
语法尚不完全清楚,我len(df['column'].unique())不需要使用lambda函数
mlh351 '18

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

如何将其导出为两列YEARMONTHcount。我也可以按降序设置计数吗?
Murtaza Haji

3

我也在使用,nunique但是如果您必须使用诸如'min', 'max', 'count' or 'mean'etc之类的聚合函数,它将非常有帮助。

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

0

使用新的Pandas版本,很容易获得数据框

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

0

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

要获取任何列(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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.