【问题标题】:Getting a column from a grouped dataframe having certain difference of two largest values of another column in each group从分组数据框中获取一列,该列与每组中另一列的两个最大值有一定的差异
【发布时间】:2021-06-10 22:26:17
【问题描述】:

我的数据框df 是:

    Election Year   Votes   Party   Region
  0   2000           50      A       a
  1   2000           100     B       a
  2   2000           70      C       a
  3   2000           26      A       b
  4   2000           180     B       b
  5   2000           100     C       b 
  6   2000           120     A       c
  7   2000           46      B       c
  8   2000           80      C       c
  9   2005           129     A       a
  10  2005           46      B       a
  11  2005           95      C       a
  12  2005           60      A       b
  13  2005           23      B       b
  14  2005           95      C       b
  15  2005           16      A       c
  16  2005           65      B       c
  17  2005           35      C       c

我想获得两个最大政党每年投票差小于 50 的地区。所以想要的输出是:

 Region
  a
  c

这两个地区的前两个政党每年的投票差为

我尝试使用“选举年份”和“地区”进行分组,然后按降序对投票进行排序。但是我无法检查每年每个地区的前两名投票之间的差异是否小于50。

我怎样才能得到想要的输出?

【问题讨论】:

    标签: python pandas dataframe data-science


    【解决方案1】:

    从你的想法开始,排序 (sort_values) + 分组 (GroupBy),然后得到差值 diff(),得到票数差值:

    >>> df = df.sort_values(['Votes'])
    >>> votes_diff = df.groupby(['Election Year', 'Region'])['Votes'].diff()
    

    我们可以加入原始数据框并在索引上重新排序以查看原始数据发生了什么:

    >>> df.join(votes_diff.rename('Δ votes')).sort_index()
        Election Year  Votes Party Region  Δ votes
    0            2000     50     A      a      NaN
    1            2000    100     B      a     30.0
    2            2000     70     C      a     20.0
    3            2000     26     A      b      NaN
    4            2000    180     B      b     80.0
    5            2000    100     C      b     74.0
    6            2000    120     A      c     40.0
    7            2000     46     B      c      NaN
    8            2000     80     C      c     34.0
    9            2005    129     A      a     34.0
    10           2005     46     B      a      NaN
    11           2005     95     C      a     49.0
    12           2005     60     A      b     37.0
    13           2005     23     B      b      NaN
    14           2005     95     C      b     35.0
    15           2005     16     A      c      NaN
    16           2005     65     B      c     30.0
    17           2005     35     C      c     19.0
    

    因此,在每次选举中,每个政党现在都有一个值Δ votes,即它比下一个政党多多少票。每次选举中最小的政党为NaN,作为其投票数。

    现在我们希望在每次选举中获得最大的 2 个政党之间的差值,即Δ votes 代表得票最多的那一行。我们或许可以使用idxmax,但由于数据框已经按投票数排序,我们也可以只使用last

    >>> top_vote_diff = votes_diff.groupby([df['Election Year'], df['Region']]).last()
    >>> top_vote_diff
    Election Year  Region
    2000           a         30.0
                   b         80.0
                   c         40.0
    2005           a         34.0
                   b         35.0
                   c         30.0
    Name: Votes, dtype: float64
    

    现在检查该地区所有选举的 lt(50) 是否小于 50:

    >>> criteria = top_vote_diff.lt(50).groupby('Region').all()
    >>> criteria
    Region
    a     True
    b    False
    c     True
    Name: Votes, dtype: bool
    >>> pd.Series(criteria.index[criteria])
    0   a
    1   c
    Name: Region, dtype: object
    

    【讨论】:

    • 感谢您的友好回复。如何找到最少两党获得超过 50 票的地区?
    • @Dpk 这是一个完全不同的问题。我认为一个布尔系列(在拥有> 50票的政党上)你可以做.groupby(...).sum() >= 2
    • 在您的第一个答案中,如何仅获取具有 True 布尔值的那些区域的列表?
    【解决方案2】:

    我会使用.pivot:

    df = df.pivot(
        index=["Region", "Election Year"], columns="Party", values="Votes"
    )
    df["diff"] = df.apply(
        lambda x: x.sort_values(ascending=False).head(2).diff()[-1] * -1, axis=1
    )
    x = df.groupby(level=0)["diff"].apply(lambda x: (x < 50).all())
    print(pd.DataFrame(x.index[x]))
    

    打印:

      Region
    0      a
    1      c
    

    步骤:

    df = df.pivot(
        index=["Region", "Election Year"], columns="Party", values="Votes"
    )
    

    创建:

    Party                   A    B    C
    Region Election Year               
    a      2000            50  100   70
           2005           129   46   95
    b      2000            26  180  100
           2005            60   23   95
    c      2000           120   46   80
           2005            16   65   35
    
    df["diff"] = df.apply(
        lambda x: x.sort_values(ascending=False).head(2).diff()[-1] * -1, axis=1
    )
    

    创建:

    Party                   A    B    C  diff
    Region Election Year                     
    a      2000            50  100   70  30.0
           2005           129   46   95  34.0
    b      2000            26  180  100  80.0
           2005            60   23   95  35.0
    c      2000           120   46   80  40.0
           2005            16   65   35  30.0
    
    x = df.groupby(level=0)["diff"].apply(lambda x: (x < 50).all())
    

    创建:

    Region
    a     True
    b    False
    c     True
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-29
      • 1970-01-01
      • 1970-01-01
      • 2017-01-02
      相关资源
      最近更新 更多