获取分组数据帧中每组中列的值递增的行

2022-03-02 00:00:00 python pandas dataframe data-science

问题描述

我的数据帧df是:

data = {'Election Year':['2000', '2000','2000','2000','2000','2000','2000','2000','2000','2005','2005','2005','2005','2005','2005','2005','2005','2005', '2010', '2010','2010','2010','2010','2010','2010','2010', '2010'],
    'Votes':[30, 50, 20, 26, 30, 45, 20, 46, 80, 60, 46, 95, 60, 10, 95, 16, 65, 35, 50, 100, 70, 26, 180, 100, 120, 46, 80], 
    'Party': ['A', 'B', 'C', 'A', 'B', 'C','A', 'B', 'C','A', 'B', 'C','A', 'B', 'C','A', 'B', 'C', 'A', 'B', 'C','A', 'B', 'C','A', 'B', 'C'],
    'Region': ['a', 'a', 'a', 'b', 'b', 'b','c', 'c', 'c','a', 'a', 'a', 'b', 'b', 'b','c', 'c', 'c','a', 'a', 'a', 'b', 'b', 'b','c', 'c', 'c']}
df = pd.DataFrame(data)
df

    
    Election Year   Votes   Party   Region
  0   2000           30      A       a
  1   2000           50      B       a
  2   2000           20      C       a
  3   2000           26      A       b
  4   2000           30      B       b
  5   2000           45      C       b 
  6   2000           20      A       c
  7   2000           46      B       c
  8   2000           80      C       c
  9   2005           60      A       a
  10  2005           66      B       a
  11  2005           95      C       a
  12  2005           60      A       b
  13  2005           10      B       b
  14  2005           95      C       b
  15  2005           16      A       c
  16  2005           65      B       c
  17  2005           35      C       c
  18  2010           50      A       a
  19  2010           100     B       a
  20  2010           70      C       a
  21  2010           26      A       b
  22  2010           180     B       b
  23  2010           100     C       b 
  24  2010           120     A       c
  25  2010           46      B       c
  26  2010           80      C       c
我想知道在接下来的两次选举中,2000年排名前两位的政党(就获得的最高总票数而言)连续增加选票的地区。 因此,所需的输出为:

   Party   Region
     B        a
     B        c
     C        b

首先,我试图根据2000年的总票数获得前两名的选票。这是给予Party&Quot;C";和&Quot;B";。

df1=df['Election Year'].eq('2000')
top_2=df[m].groupby(['Election Year','Party'],as_index=False) 
       ['Votes'].sum().sort_values('Votes',ascending=False).head(2)['Party'].values
top_2

这将给交易方&Quot;C";和&Quot;B";提供。

现在我如何检查这些政党的选票在随后几年增加的地区?


解决方案

我喜欢Rob Raymond的回答,但我只想强调另外几件可能对解决此类问题有用的事情。对于此类分析,最好将";Party";和";Region&Quot;列作为索引来查看数据。

如果我们这样做

grps = ["Party", "Region"]  # I do this because we will use these later
df = df.set_index(grps).sort_index()

那么df现在看起来像

             Election Year  Votes
Party Region
A     a               2000     30
      a               2005     60
      a               2010     50
      b               2000     26
      b               2005     60
      b               2010     26
      c               2000     20
      c               2005     16
      c               2010    120
B     a               2000     50
      a               2005     46
      a               2010    100
      b               2000     30
      b               2005     10
      b               2010    180
      c               2000     46
      c               2005     65
      c               2010     46
C     a               2000     20
      a               2005     95
      a               2010     70
      b               2000     45
      b               2005     95
      b               2010    100
      c               2000     80
      c               2005     35
      c               2010     80

我认为这更容易通过目测和交叉核对来研究。例如,根据我对您问题的理解,票数每年增加的唯一政党/地区是2000年的45票、2005年的95票和2010年的100票。

但是如果数据太大而无法查看怎么办?那么我们可以按新索引分组(记住这现在是";Party";和";region";),并将diff方法应用于";Votes&Quot;列。我们将此结果重新分配给一个名为";Vote diff&qot;的新列。

df["Vote Diff"] = df.groupby(grps)["Votes"].diff()

现在df

             Election Year  Votes  Vote Diff
Party Region
A     a               2000     30        NaN
      a               2005     60       30.0
      a               2010     50      -10.0
      b               2000     26        NaN
      b               2005     60       34.0
      b               2010     26      -34.0
      c               2000     20        NaN
      c               2005     16       -4.0
      c               2010    120      104.0
B     a               2000     50        NaN
      a               2005     46       -4.0
      a               2010    100       54.0
      b               2000     30        NaN
      b               2005     10      -20.0
      b               2010    180      170.0
      c               2000     46        NaN
      c               2005     65       19.0
      c               2010     46      -19.0
C     a               2000     20        NaN
      a               2005     95       75.0
      a               2010     70      -25.0
      b               2000     45        NaN
      b               2005     95       50.0
      b               2010    100        5.0
      c               2000     80        NaN
      c               2005     35      -45.0
      c               2010     80       45.0

现在我们可以很容易地看到投票的起伏。对于您要做的事情,我们目前不太关心2000年,因此我们可以在下一部分使用drona安全地删除带有NaN的行。

我们现在需要对党/地区的群组进行过滤,只保留群组中所有值都为正值(即投票数每年都在增加)的群组。我们可以在groupby对象上使用filter来做到这一点。我们需要一个小函数来测试这是否为真,这里我使用的是lambda,但您也可以只定义它。

out = df.dropna().groupby(grps).filter(lambda x: (x["Vote Diff"] > 0).all())

提供

             Election Year  Votes  Vote Diff
Party Region
C     b               2005     95       50.0
      b               2010    100        5.0

瞧!我们看到票数同比增长的只有C/b地区。

我们没有研究如何将此与您的顶级交易方要求相结合,但是您有一个顶级交易方列表,这很简单(对top_2代码稍作修改)

top_2 = (df[df["Election Year"] == "2000"]
           .groupby("Party")["Votes"].sum()
           .nlargest(2))
out.loc[top_2.index]

将所有内容放在一起

top_2 = (df[df["Election Year"] == "2000"]
           .groupby("Party")["Votes"].sum()
           .nlargest(2))

grps = ["Party", "Region"]
df = df.set_index(grps).sort_index()
df["Vote Diff"] = df.groupby(grps)["Votes"].diff()
df.dropna().groupby(grps).filter(lambda x: (x["Vote Diff"] > 0).all()).loc[top_2.index]

相关文章