【问题标题】:Count unique values per groups with Pandas [duplicate]使用 Pandas 计算每个组的唯一值 [重复]
【发布时间】:2016-11-13 13:33:46
【问题描述】:

我需要计算每个 domain 中唯一的 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

【问题讨论】:

    标签: python pandas group-by unique pandas-groupby


    【解决方案1】:

    如果我理解正确,您需要每个 domain 的不同 IDs 的数量。然后你可以试试这个:

    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's answer 使用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
    

    【讨论】:

    • value_counts 在较大的数据帧上稍快:i.imgur.com/V8kcVb8.png
    • @ayhan 我应该尝试更大的数据帧,我的错。谢谢你指出!
    【解决方案2】:

    你需要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。

    【讨论】:

    • 奇怪,但对于我的数据,它返回所有域的数量,而不是唯一用户
    • 有趣,它适用于样本而不适用于真实数据?
    • df.groupby(df.domain.str.strip("'"))['ID'].nunique() 返回正确,但 df = df.groupby('domain')['ID'].nunique() 不正确
    • 对于这个代码块: df = df.groupby('domain')['ID'].nunique() ;有谁知道如何使输出成为数据框中的一列?
    • @00schneider - 你是对的,我的第一个解决方案。
    【解决方案3】:

    df.domain.value_counts()

    >>> df.domain.value_counts()
    
    vk.com          5
    
    twitter.com     2
    
    google.com      1
    
    facebook.com    1
    
    Name: domain, dtype: int64
    

    【讨论】:

    • df.isnull().any(axis=1).value_counts()
    【解决方案4】:

    一般要计算单列中的不同值,可以使用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.arraydrop_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
    

    【讨论】:

    • 如果有人想知道,我相信df.groupby('foo')['foo'].count() == df['foo'].value_counts()
    猜你喜欢
    • 1970-01-01
    • 2018-07-26
    • 2012-10-25
    • 2020-10-06
    相关资源
    最近更新 更多