Python 数据帧上的条件筛选器和groupby

Python 数据帧上的条件筛选器和groupby,python,pandas,Python,Pandas,我有一个具有以下结构的数据帧: date kind sector 0 2017-02-01 P A 1 2017-02-01 P A 2 2017-02-01 L A 3 2017-02-01 G A 4 2017-02-01 P B 5 2017-02-01 P B 6 2017-02-01 L B 7 2017-02-01 T B 8 2017-02-02 P A 9 2017-

我有一个具有以下结构的数据帧:

    date    kind    sector
0   2017-02-01  P   A
1   2017-02-01  P   A
2   2017-02-01  L   A
3   2017-02-01  G   A
4   2017-02-01  P   B
5   2017-02-01  P   B
6   2017-02-01  L   B
7   2017-02-01  T   B
8   2017-02-02  P   A
9   2017-02-02  P   A
10  2017-02-02  L   A
11  2017-02-02  T   A
12  2017-02-02  A   B
13  2017-02-02  P   B
14  2017-02-02  L   B
15  2017-02-02  L   B
我想用以下格式创建一个聚合

    date      sector free occupied total
   2017-02-01  A      2    2         4
   2017-02-01  B      2    2         4
   2017-02-02  A      2    2         4
   2017-02-02  A      3    1         4
其中的规则是,如果
kind==p
被占用,则else是自由的,并且总数是所有条目的总和。我试着用
apply
对一组人进行测试,但没有成功:

df.groupby(['date', 'kind']).apply(lambda x: 1 if x == 'P' else 0)
df_p = df[df.kind == 'P']
df_np = df[df.kind != 'P']
df_t = df_p.groupby(['date', 'sector'], as_index=False).count()
df_nt = df_np.groupby(['date', 'sector'], as_index=False).count()
df_nt.rename(columns={'kind':'free'}, inplace=True)
df_t = pd.concat([df_t, df_nt])
拆分数据帧并合并也不起作用:

df.groupby(['date', 'kind']).apply(lambda x: 1 if x == 'P' else 0)
df_p = df[df.kind == 'P']
df_np = df[df.kind != 'P']
df_t = df_p.groupby(['date', 'sector'], as_index=False).count()
df_nt = df_np.groupby(['date', 'sector'], as_index=False).count()
df_nt.rename(columns={'kind':'free'}, inplace=True)
df_t = pd.concat([df_t, df_nt])

有没有办法进行此计数?

为“占用”和“空闲”创建两个新变量:

然后聚合(在此处使用
OrderedDict
而不是
dict
以实现所需的输出列顺序):

并创建您的总计列:

df_2["total"] = df_2["free"] + df_2["occupied"]
输出:

试试:

df['kind'] = df.kind.apply(lambda x: 'occupied' if x == 'P' else 'free')
df1 = pd.get_dummies(df.kind).join(df).groupby(['date','sector']).sum().reset_index()
df1['total'] = df1['occupied']+df1['free']    
df1

    #          date sector  free  occupied  total
    # 0  2017-02-01      A     2         2      4
    # 1  2017-02-01      B     2         2      4
    # 2  2017-02-02      A     2         2      4
    # 3  2017-02-02      B     3         1      4
在这里,您要做的是:首先在
kind
列中将p替换为acquired,将其他所有内容替换为free。然后,使用
pd.get\u dummies
对新格式化的
kind
中的值进行分类。然后,该输出被连接回主数据帧。此时,您可以按
日期
扇区
进行分组,并取每个扇区的
。最后,您可以
reset_index
并计算
total


我希望这能有所帮助。

这里有一个简单的例子:

#group by date and sector, apply 3 functions to kind to get the sum for free, occupied and total in one go.
df.groupby(['date','sector'])['kind'].agg({'free':lambda x: sum(x!='P'),'occupied':lambda x: sum(x=='P'), 'total':len})
Out[339]: 
                   free  occupied  total
date       sector                       
2017-02-01 A          2         2      4
           B          2         2      4
2017-02-02 A          2         2      4
           B          3         1      4
更详细的方法:

#Transform the kind column to free or occupied only
df.kind = df.kind.replace('[^P]','free',regex=True).replace('P','occupied')
#Convert kind from long to wide columns
df = pd.get_dummies(df,columns=['kind'],prefix='',prefix_sep='')
#get total
df['total']=df.free+df.occupied
#groupby and sum
df.groupby(['date','sector']).sum()
Out[322]: 
                   free  occupied  total
date       sector                       
2017-02-01 A          2         2      4
           B          2         2      4
2017-02-02 A          2         2      4
           B          3         1      4

所需输出的最后一行是错误的吗
2017-02-01 A 3 1 4
您似乎在重复
2017-02-01 A
修复了那里的打字错误。