从分组数据框中获取一列,该列具有每组中另一列的两个最大值的某些差异
Getting a column from a grouped dataframe having certain difference of two largest values of another column in each group
我的数据框 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。
我尝试使用“选举年”和“地区”进行分组,然后按降序对投票进行排序。但是我无法检查每年每个地区的前两名票数之间的差异是否小于50。
如何获得所需的输出?
我会使用 .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
从你的想法出发,排序(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
现在检查该地区的所有选举是否少于 50 lt(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
我的数据框 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。
我尝试使用“选举年”和“地区”进行分组,然后按降序对投票进行排序。但是我无法检查每年每个地区的前两名票数之间的差异是否小于50。
如何获得所需的输出?
我会使用 .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
从你的想法出发,排序(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
现在检查该地区的所有选举是否少于 50 lt(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