Pandas:按组大小和数据值进行筛选

6

我将数据分组后,希望从结果中删除只包含单个观察值且值低于某个阈值的组。

初始数据:

df = pd.DataFrame(data={'Province' : ['ON','QC','BC','AL','AL','MN','ON'], 
                            'City' :['Toronto','Montreal','Vancouver','Calgary','Edmonton','Winnipeg','Windsor'],
                            'Sales' : [13,6,16,8,4,3,1]})

        City Province  Sales
0    Toronto       ON     13
1   Montreal       QC      6
2  Vancouver       BC     16
3    Calgary       AL      8
4   Edmonton       AL      4
5   Winnipeg       MN      3
6    Windsor       ON      1

现在需要对数据进行分组:
df.groupby(['Province', 'City']).sum()

                    Sales
Province City
AL       Calgary        8
         Edmonton       4
BC       Vancouver     16
MN       Winnipeg       3
ON       Toronto       13
         Windsor        1
QC       Montreal       6

现在我无法理解的是如何删除只有一个城市(或通常是N个观测值)且总销售额小于10的省份。预期输出应为:

                    Sales
Province City
AL       Calgary        8
         Edmonton       4
BC       Vancouver     16
ON       Toronto       13
         Windsor        1

即MN/Winnipeg和QC/Montreal已从结果中消失。理想情况下,它们不会完全消失,而是合并为一个名为“其他”的新组,但这可能是另一个问题的内容。

2个回答

10

你可以这样做:

In [188]: df
Out[188]:
        City Province  Sales
0    Toronto       ON     13
1   Montreal       QC      6
2  Vancouver       BC     16
3    Calgary       AL      8
4   Edmonton       AL      4
5   Winnipeg       MN      3
6    Windsor       ON      1

In [189]: g = df.groupby(['Province', 'City']).sum().reset_index()

In [190]: g
Out[190]:
  Province       City  Sales
0       AL    Calgary      8
1       AL   Edmonton      4
2       BC  Vancouver     16
3       MN   Winnipeg      3
4       ON    Toronto     13
5       ON    Windsor      1
6       QC   Montreal      6

现在我们将为那些'拥有超过一个城市的省份'创建一个掩码:

In [191]: mask = g.groupby('Province').City.transform('count') > 1

In [192]: mask
Out[192]:
0     True
1     True
2    False
3    False
4     True
5     True
6    False
dtype: bool

总销售额大于或等于10的城市获胜:

In [193]: g[(mask) | (g.Sales >= 10)]
Out[193]:
  Province       City  Sales
0       AL    Calgary      8
1       AL   Edmonton      4
2       BC  Vancouver     16
4       ON    Toronto     13
5       ON    Windsor      1

filter 可以以任何方式使用吗? - Dmitry B.
@DmitryB.,我还不知道。但这与你最初的问题有何关联? - MaxU - stand with Ukraine
另外,我有一种直觉,如果有一种使用“filter”的方法,可能需要更少的步骤来完成这个任务。 - Dmitry B.
看起来 filter 允许更高效的计算(请参见我的答案) - Dmitry B.

6

我对给出的所有答案都不太满意,所以我一直在琢磨,最终找到了以下解决方案:

In [72]: df
Out[72]:
        City Province  Sales
0    Toronto       ON     13
1   Montreal       QC      6
2  Vancouver       BC     16
3    Calgary       AL      8
4   Edmonton       AL      4
5   Winnipeg       MN      3
6    Windsor       ON      1

In [73]: df.groupby(['Province', 'City']).sum().groupby(level=0).filter(lambda x: len(x)>1 or x.Sales > 10)
Out[73]:
                    Sales
Province City
AL       Calgary        8
         Edmonton       4
BC       Vancouver     16
ON       Toronto       13
         Windsor        1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接