Python pandas中通过groupby函数汇总唯一值的实现求助
嘿,我来帮你搞定这个pandas分组统计的问题!
首先,咱们先理清你的需求:你想要按Block分组,统计两个指标——一是每个分组里EID的唯一数量,二是每个唯一EID对应的Hours值的总和(从你的预期结果反推,你应该是这个意思,因为如果单纯是Hours的唯一值求和,STG组的结果应该是1.0而不是2.0)。
先说说你之前代码的问题:那个lambda x: sum(range(int(x.max())))完全偏离了需求——它是取Hours列的最大值转成整数,然后计算从0到这个整数的累加和,比如STG组的Hours最大值是1.0,转成int是1,sum(range(1))结果是0,这显然不是你要的。
接下来给你两种场景的解决方案,对应不同的需求:
场景1:如果确实需要Hours的唯一值求和(去重后直接相加)
比如STG组的Hours唯一值只有1.0,求和结果是1.0:
import pandas as pd # 构造你的示例数据 data = { 'EID': [5443, 5443, 5402, 5223], 'Hours': [1.0, 1.0, 3.5, 1.0], 'Block': ['STG', 'STG', 'BZP', 'STG'], 'Participant': ['x', 'y', 'a', 'z'] } df = pd.DataFrame(data) # 分组聚合 result = df.groupby('Block').agg( Unique_count=('EID', 'nunique'), Unique_sum=('Hours', lambda x: x.unique().sum()) ).reset_index() # 调整列名匹配你的格式 result.columns = ['Block', 'Unique count', 'Unique sum'] print(result)
输出结果:
Block Unique count Unique sum 0 BZP 1 3.5 1 STG 2 1.0
场景2:匹配你的预期结果(每个唯一EID的Hours求和)
也就是同一个EID在同一个Block下只保留一条记录,再对Hours求和:
import pandas as pd # 构造示例数据 data = { 'EID': [5443, 5443, 5402, 5223], 'Hours': [1.0, 1.0, 3.5, 1.0], 'Block': ['STG', 'STG', 'BZP', 'STG'], 'Participant': ['x', 'y', 'a', 'z'] } df = pd.DataFrame(data) # 先按Block和EID去重,每个EID在对应Block下只留一条 unique_eid_df = df.drop_duplicates(subset=['Block', 'EID']) # 再分组统计 result = unique_eid_df.groupby('Block').agg( Unique_count=('EID', 'count'), # 这里用count或nunique结果一致 Unique_sum=('Hours', 'sum') ).reset_index() # 调整列名 result.columns = ['Block', 'Unique count', 'Unique sum'] print(result)
输出结果完全匹配你的预期:
Block Unique count Unique sum 0 BZP 1 3.5 1 STG 2 2.0
核心思路就是先确保每个EID在分组内只出现一次,再对Hours求和,这样就能得到你想要的结果啦。
内容的提问来源于stack exchange,提问作者Prateek Srivastava
相关产品推荐
相关产品推荐

