Python Groupby基于应用于不同列数据帧的多个逻辑条件

Python Groupby基于应用于不同列数据帧的多个逻辑条件,python,pandas,Python,Pandas,我有这个数据框: df = pd.DataFrame({'value':[1,2,3,4,2,42,12,21,21,424,34,12,42], 'type':['big','small','medium','big','big','big','big','medium','small','small','small','medium','small'], 'entity':['R','R','R','P','R','P','P','P','R','R','P','R','R']})

我有这个数据框:

df = pd.DataFrame({'value':[1,2,3,4,2,42,12,21,21,424,34,12,42],
'type':['big','small','medium','big','big','big','big','medium','small','small','small','medium','small'],
'entity':['R','R','R','P','R','P','P','P','R','R','P','R','R']})

    value    type  entity
0       1     big       R
1       2   small       R
2       3  medium       R
3       4     big       P
4       2     big       R
5      42     big       P
6      12     big       P
7      21  medium       P
8      21   small       R
9     424   small       R
10     34   small       P
11     12  medium       R
12     42   small       R
condition = (f.type!="medium") & (f.value>3)
该操作包括按列“实体”分组,根据应用于列“值”和列“类型”的两个逻辑条件执行计数操作。在我的例子中,我必须计算“name”列中大于3的值,并且不等于“type”列中的“medium”。结果必须是R=3和P=4。在此之后,我必须将结果添加到原始数据框中,创建一个名为“Count”的新列。 我知道这个操作可以通过下一个代码在R中完成:

df[y!='medium' & value>3 , new_var:=.N,by=entity]
df[is.na(new_var),new_var:=0,]
df[,new_var:=max(new_var),by=entity]

In []:  df.groupby(['entity'])['value'].apply(lambda x: (x>3).sum())

Out[]:  entity
        P    5
        R    4
        Name: value, dtype: int64

In []:  DF=pd.DataFrame(DF)
In []:  DF.reset_index(inplace=True)
In []:  df.merge(DF,on=['entity'],how='inner')
In []:  df=df.rename(columns={'value_x':'value','value_y':'count'},inplace=True)
Out[]:  

    value   type     entity  count
0      1     big          R      4
1      2   small          R      4
2      3  medium          R      4
3      2     big          R      4
4     21   small          R      4
5    424   small          R      4
6     12  medium          R      4
7     42   small          R      4
8      4     big          P      5
9     42     big          P      5
10    12     big          P      5
11    21  medium          P      5
12    34   small          P      5
在上一个任务中,我必须只计算大于3的值作为条件。在这种情况下,结果是R=3和P=4,我应用下一个代码得到:

df[y!='medium' & value>3 , new_var:=.N,by=entity]
df[is.na(new_var),new_var:=0,]
df[,new_var:=max(new_var),by=entity]

In []:  df.groupby(['entity'])['value'].apply(lambda x: (x>3).sum())

Out[]:  entity
        P    5
        R    4
        Name: value, dtype: int64

In []:  DF=pd.DataFrame(DF)
In []:  DF.reset_index(inplace=True)
In []:  df.merge(DF,on=['entity'],how='inner')
In []:  df=df.rename(columns={'value_x':'value','value_y':'count'},inplace=True)
Out[]:  

    value   type     entity  count
0      1     big          R      4
1      2   small          R      4
2      3  medium          R      4
3      2     big          R      4
4     21   small          R      4
5    424   small          R      4
6     12  medium          R      4
7     42   small          R      4
8      4     big          P      5
9     42     big          P      5
10    12     big          P      5
11    21  medium          P      5
12    34   small          P      5

我的问题是:在两种情况下,我该如何做?事实上,对于具有多个不同条件的一般情况,我该如何执行此操作?

根据您的条件创建掩码-此处用于按位<代码>和的“较大者”和“不相等者”链接,然后用于按<代码>和计数<代码>为真和<代码>求和:

mask = df['value'].gt(3) & df['type'].ne('medium')
df['count'] = mask.groupby(df['entity']).transform('sum')
带有辅助列的解决方案
新建

mask = df['value'].gt(3) & df['type'].ne('medium')
df['count'] = df.assign(new = mask).groupby('entity')['new'].transform('sum')


熊猫的解决方案非常好。这是另一个包中的替代方案。我之所以把它放在这里,是因为原始代码位于R中的
data.table
,它可能对其他人有用,他们可能希望在Python中使用类似的解决方案

这是中的一个解决方案,该库旨在用python复制
data.table
。注意,它的特征不如熊猫丰富;希望随着时间的推移,更多的功能将被添加

使用
数据表创建框架

   from datatable import dt, f, by, update

    df = dt.Frame({'value':[1,2,3,4,2,42,12,21,21,424,34,12,42],
'type':['big','small','medium','big','big','big','big','medium','small','small','small','medium','small'],
'entity':['R','R','R','P','R','P','P','P','R','R','P','R','R']})
创建条件-在datatable中,
f
符号是引用数据框的快捷方式:

df = pd.DataFrame({'value':[1,2,3,4,2,42,12,21,21,424,34,12,42],
'type':['big','small','medium','big','big','big','big','medium','small','small','small','medium','small'],
'entity':['R','R','R','P','R','P','P','P','R','R','P','R','R']})

    value    type  entity
0       1     big       R
1       2   small       R
2       3  medium       R
3       4     big       P
4       2     big       R
5      42     big       P
6      12     big       P
7      21  medium       P
8      21   small       R
9     424   small       R
10     34   small       P
11     12  medium       R
12     42   small       R
condition = (f.type!="medium") & (f.value>3)
数据表的用户应熟悉以下语法

 DT[i, j, by] 
其中,
i
表示行中可能出现的任何内容,
j
表示列操作,
by
表示分组操作。该函数在功能上类似于
:=
数据表中的函数;它允许创建新列或更新现有列

df[:, update(count=dt.sum(condition)), by('entity')]

df

 value  type    entity  count
0   1   big     R       3
1   2   small   R       3
2   3   medium  R       3
3   4   big     P       4
4   2   big     R       3
5   42  big     P       4
6   12  big     P       4
7   21  medium  P       4
8   21  small   R       3
9   424 small   R       3
10  34  small   P       4
11  12  medium  R       3
12  42  small   R       3

非常感谢。这个答案给了我一些类似任务的解决方案。太棒了!。在这些情况下,这个替代方案让熟悉R的人得到一个好的解决方案。非常感谢。R(data.table)代码可以简化为
df[,new_var:=max(.N*(y!=“medium”&value>3)),by=entity]