Skip to main content
 首页 » 编程设计

python之如何获取 Pandas Dataframe 中由 groupby 组合的行的值列表

2025年05月04日11del

假设我有以下数据框:

#!/usr/bin/env python 
 
import pandas as pd 
 
 
df = pd.DataFrame([(1, 2, 1), 
                   (1, 2, 2), 
                   (1, 2, 3), 
                   (4, 1, 612), 
                   (4, 1, 612), 
                   (4, 1, 1), 
                   (3, 2, 1), 
                   ], 
                  columns=['groupid', 'a', 'b'], 
                  index=['India', 'France', 'England', 'Germany', 'UK', 'USA', 
                         'Indonesia']) 
print(df) 

给出:

           groupid  a    b 
India            1  2    1 
France           1  2    2 
England          1  2    3 
Germany          4  1  612 
UK               4  1  612 
USA              4  1    1 
Indonesia        3  2    1 

第一步

这一步可能不是必需的/与我想象的不同。我实际上只对第 2 步感兴趣,但有了它可以帮助我思考它并解释我想要什么。

我想按 groupid (df.groupby(df['groupid'])) 对数据进行分组并得到如下内容:

    groupid  a    b 
          1  [2]  [1, 2, 3] 
          4  [1]  [612, 1] 
          3  [2]  [1] 

第二步

然后我想找到在 b 列中只有一个条目且条目等于 1 的所有组 ID。

同样,我想找到所有具有多个条目或一个不是 1 的条目的组 ID。

请您参考如下方法:

您可以比较set,然后获取list的索引值:

mask = df.groupby('groupid')['b'].apply(set) == set([1]) 
print (mask) 
groupid 
1    False 
3     True 
4    False 
Name: b, dtype: bool 
 
i = mask.index[mask].tolist() 
print (i) 
[3] 
 
j = mask.index[~mask].tolist() 
print (j) 
[1, 4] 

对于新列使用map:

df['new'] = df['groupid'].map(df.groupby('groupid')['b'].apply(set) == set([1])) 
print (df) 
 
           groupid  a    b    new 
India            1  2    1  False 
France           1  2    2  False 
England          1  2    3  False 
Germany          4  1  612  False 
UK               4  1  612  False 
USA              4  1    1  False 
Indonesia        3  2    1   True 

旧的解决方案:

您可以使用 transform与 nunique对于与原始 df 大小相同的新 Series,因此可以将其与 1 进行比较以获得唯一性,然后链接另一个条件以与 1 进行比较:

mask = (df.groupby('groupid')['b'].transform('nunique') == 1) & (df['b'] == 1) 
print (mask) 
India        False 
France       False 
England      False 
Germany      False 
UK           False 
USA          False 
Indonesia     True 
Name: b, dtype: bool 

对于 list 中的唯一值:

i = df.loc[mask, 'groupid'].unique().tolist() 
print (i) 
[3] 
 
j = df.loc[~mask, 'groupid'].unique().tolist() 
print (j) 
[1, 4] 

详细信息:

print (df.groupby('groupid')['b'].transform('nunique')) 
India        3 
France       3 
England      3 
Germany      2 
UK           2 
USA          2 
Indonesia    1 
Name: b, dtype: int64