获取分组数据帧中每组中列的值递增的行
问题描述
我的数据帧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]
相关文章