python中groupby可以按照条件计算分组吗_python - Pandas中groupby分组统计唯一值的2种方法...

问题描述:我需要在每个有数据的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

即每个domain分组中不同的“ID”数量。

方法一:

您需要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

或者:

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。

方法二

通常,要在单列中计算不同的值,可以使用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

要获取所有这些不同的值,可以使用unique或drop_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

不同方法的性能对比

对于第二种方法,也可以尝试以下操作:

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,但是最好的方法是使用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

参考资料

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值