使用Pandas按组计算唯一值的数量

343
我需要统计每个域中唯一的ID值。
我有数据:
 ID, domain
123, vk.com
123, vk.com
123, twitter.com
456, vk.com'
456, facebook.com
456, vk.com
456, google.com
789, twitter.com
789, vk.com

我尝试使用df.groupby(['domain', 'ID']).count(),但我想要得到的是
domain       count
vk.com        3
twitter.com   2
facebook.com  1
google.com    1
4个回答

425
你需要 nunique 函数:
df = df.groupby('domain')['ID'].nunique()

print (df)
domain
'facebook.com'    1
'google.com'      1
'twitter.com'     2
'vk.com'          3
Name: ID, dtype: int64

如果你需要去除字符中的',可以使用strip函数:
df = df.ID.groupby([df.domain.str.strip("'")]).nunique()
print (df)
domain
facebook.com    1
google.com      1
twitter.com     2
vk.com          3
Name: ID, dtype: int64

或者像Jon Clements评论的那样:

df.groupby(df.domain.str.strip("'"))['ID'].nunique()

您可以这样保留列名:
df = df.groupby(by='domain', as_index=False).agg({'ID': pd.Series.nunique})
print(df)
    domain  ID
0       fb   1
1      ggl   1
2  twitter   2
3       vk   3

区别是nunique()返回Series,而agg()返回DataFrame。


353

一般来说,如果要统计单列中的唯一值数量,可以使用 Series.value_counts 方法:

df.domain.value_counts()

#'vk.com'          5
#'twitter.com'     2
#'facebook.com'    1
#'google.com'      1
#Name: domain, dtype: int64

要查看一列中有多少个唯一值,请使用Series.nunique

df.domain.nunique()
# 4

要获取所有这些不同的值,您可以使用 uniquedrop_duplicates,这两个函数之间的轻微差别在于 unique 返回一个 numpy.array,而 drop_duplicates 返回一个 pandas.Series

df.domain.unique()
# array(["'vk.com'", "'twitter.com'", "'facebook.com'", "'google.com'"], dtype=object)

df.domain.drop_duplicates()
#0          'vk.com'
#2     'twitter.com'
#4    'facebook.com'
#6      'google.com'
#Name: domain, dtype: object
对于这个具体的问题,除了其他答案中提供的groupby方法之外,您还可以首先简单地去重,然后再使用value_counts()来计算相关变量的不同值数量。
import pandas as pd
df.drop_duplicates().domain.value_counts()

# 'vk.com'          3
# 'twitter.com'     2
# 'facebook.com'    1
# 'google.com'      1
# Name: domain, dtype: int64

70

df.domain.value_counts()

>>> df.domain.value_counts()

vk.com          5

twitter.com     2

google.com      1

facebook.com    1

Name: domain, dtype: int64

18

如果我理解正确,您想知道每个 domain 的不同 ID 数量。那么您可以尝试这样做:

output = df.drop_duplicates()
output.groupby('domain').size()

输出:

    domain
facebook.com    1
google.com      1
twitter.com     2
vk.com          3
dtype: int64

您还可以使用value_counts,这样效率略低。但最好的方法是Jezrael的答案,使用nunique

%timeit df.drop_duplicates().groupby('domain').size()
1000 loops, best of 3: 939 µs per loop
%timeit df.drop_duplicates().domain.value_counts()
1000 loops, best of 3: 1.1 ms per loop
%timeit df.groupby('domain')['ID'].nunique()
1000 loops, best of 3: 440 µs per loop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接