查找每个组的唯一项目数

2024-10-02 00:32:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个dfA看起来像

type    number    date 
1       1         2017-10-01
2       1         2017-10-31
1       2         2017-09-01
1       2         2017-08-01
2       2         2017-06-01

首先我想按number分组,并选择每个组至少需要包含一行type == 1和一行type == 2的组;为此,我首先检查每个组的大小必须为>;2号

g = A.groupby('number')
B = g.filter(lambda x: len(x) > 1) # df B gets the filter results on g  

但我不知道如何也检查type12包含在上面获得的每个组中

其次,基于从步骤1获得的组,我想在A中创建一个名为type_2_before_type_1的布尔列,如果最早的datefor type 1减去最早的datefor type 2是<0表示每组,否则False。因为在每个组中可能有许多带有type == 1的行和许多带有type == 2的行(如何获得类型1和类型2行的g['A'].transform('min')?)。所以结果dfA看起来像

type    number    date         type_2_before_type_1
1       1         2017-10-01   True
2       1         2017-10-31   True
1       2         2017-09-01   False
1       2         2017-08-01   False
2       2         2017-06-01   False

例如,对于具有number == 2的组,类型1 2017-08-01的最早日期减去类型2 2017-06-01的最早日期,结果为61天;因此,将False设置为type_2_before_type_1


Tags: lambdagtfalsetrue类型numberdfdate
2条回答

对于第一部分,使用groupby+nunique-

df.groupby('number').type.transform('nunique')

0    2
1    2
2    2
3    2
4    2
Name: type, dtype: int64

df = df[df.groupby('number').type.transform('nunique').gt(1)]

   type  number        date
0     1       1  2017-10-01
1     2       1  2017-10-31
2     1       2  2017-09-01
3     1       2  2017-08-01
4     2       2  2017-06-01

第二部分有点挑战性,但是你可以groupbyunstack,调用diff,然后得到一个掩码-

df['type_2_before_type_1'] = \
 df.groupby(['number', 'type'])\
      .first()\
      .unstack()\
      .diff(-1, axis=1)\
      .iloc[:, 0]\
      .reindex(df.number)\
      .astype(int)\
      .lt(0)\
      .values

df

   type  number       date  type_2_before_type_1
0     1       1 2017-10-01                  True
1     2       1 2017-10-31                  True
2     1       2 2017-09-01                 False
3     1       2 2017-08-01                 False
4     2       2 2017-06-01                 False
g=df.groupby('number')
i=g.apply(lambda x : min(x['date'][x.type==1]))
j=g.apply(lambda x : min(x['date'][x.type==2]))
k=g.type.nunique()==2
df['New'] = df.number.map(~(i > j) & k)
df
Out[588]: 
   type  number       date    New
0     1       1 2017-10-01   True
1     2       1 2017-10-31   True
2     1       2 2017-09-01  False
3     1       2 2017-08-01  False
4     2       2 2017-06-01  False

相关问题 更多 >

    热门问题