首页 > 解决方案 > 在分组的 Pandas 数据框中获取最常见的值

问题描述

我有一个这样的DF:
Date DIS_NR NUM_EMPLOYEES
8/16/2018 868 200
8/17/2018 868 150
8/18/2018 868 200
8/16/2018 776 150
8/17/2018 776 250
8/18/2018 776 150

现在,对于每个 DIS_NR,必须使用出现次数最多的 NUM_EMPLOYEES 值作为基准,并且必须标记任何其他不具有相同值的日期。

最终数据应如下所示:

Date DIS_NR NUM_EMPLOYEES FLAG
8/16/2018 868 200 0
8/17/2018 868 150 1
8/18/2018 868 200 0
8/16/2018 776 150 0
8/17/2018 776 250 1
8/18/2018 776 150 0

我使用 Date 和 DIS_NR 进行分组,
df1 = DF.groupby(["DIS_NR", "Date"])
我尝试循环遍历每一个并找到模式,但它不起作用。任何帮助,将不胜感激。

谢谢你。

标签: pythonpandas

解决方案


从您的问题来看,您似乎Date对分组中的列不知道:

>>> func = lambda s: s.ne(s.value_counts().idxmax()).astype(int)
>>> df['FLAG'] = df.groupby('DIS_NR')['NUM_EMPLOYEES'].apply(func)

>>> df
        Date  DIS_NR  NUM_EMPLOYEES  FLAG
0 2018-08-16     868            200     0
1 2018-08-17     868            150     1
2 2018-08-18     868            200     0
3 2018-08-16     776            150     0
4 2018-08-17     776            250     1
5 2018-08-18     776            150     0

groupby().transform()通常并不总是最快的路线,但在这种情况下,它应该能够使用一些 Cython 例程,因为其中使用的方法func是矢量化的。(而不是需要在 Python 中进行。)

当您将函数传递给 时.transform(),它会应用于每个子集系列,您可以通过以下方式查看.get_groups()

>>>  df.groupby('DIS_NR')['NUM_EMPLOYEES'].get_group(868)
0    200
1    150
2    200
Name: NUM_EMPLOYEES, dtype: int64

>>>  df.groupby('DIS_NR')['NUM_EMPLOYEES'].get_group(776)
3    150
4    250
5    150
Name: NUM_EMPLOYEES, dtype: int64

>>> func(df.groupby('DIS_NR')['NUM_EMPLOYEES'].get_group(868))
0    0
1    1
2    0
Name: NUM_EMPLOYEES, dtype: int64

更新:

例如,如果 DIS_NR 825 具有值 (125,243,221),则应标记所有值。

>>> df
        Date  DIS_NR  NUM_EMPLOYEES
0 2018-08-16     868            200
1 2018-08-17     868            150
2 2018-08-18     868            200
3 2018-08-16     776            150
4 2018-08-17     776            250
5 2018-08-18     776            150
6 2018-08-16     825            100
7 2018-08-17     825            100
8 2018-08-18     825            100

在这种情况下,您可以对唯一值的数量进行第二个条件测试。另请注意,您使用的是.transform()而不是.apply()

func = lambda s: np.where(
    s.nunique() == 1, 1,
    s.ne(s.value_counts().idxmax()).astype(int)
)

>>> df.groupby('DIS_NR')['NUM_EMPLOYEES'].transform(func)
0    0
1    1
2    0
3    0
4    1
5    0
6    1
7    1
8    1
Name: NUM_EMPLOYEES, dtype: int64

推荐阅读