如何在Pandas Dataframe中获取groupby组合的行的值列表?

Mar*_*oma 1 python pandas pandas-groupby

假设我有以下数据帧:

#!/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)
Run Code Online (Sandbox Code Playgroud)

这使:

           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
Run Code Online (Sandbox Code Playgroud)

步骤1

这个步骤可能没有必要/与我想象的不同.我实际上只对第2步感兴趣,但这有助于我思考并解释我想要的东西.

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

    groupid  a    b
          1  [2]  [1, 2, 3]
          4  [1]  [612, 1]
          3  [2]  [1]
Run Code Online (Sandbox Code Playgroud)

第2步

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

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

jez*_*ael 5

你可以比较sets,然后获得索引的值为lists:

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]
Run Code Online (Sandbox Code Playgroud)

对于新列使用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
Run Code Online (Sandbox Code Playgroud)

旧解决方案:

您可以使用transform与原始df相同大小的nuniquenew 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
Run Code Online (Sandbox Code Playgroud)

对于lists中的唯一值:

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

j = df.loc[~mask, 'groupid'].unique().tolist()
print (j)
[1, 4]
Run Code Online (Sandbox Code Playgroud)

详情:

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
Run Code Online (Sandbox Code Playgroud)