![](/img/trans.png)
[英]Creating a new column based on several groupby conditions in python
[英]Python DataFrames - Help needed with creating a new column based on several conditionals
我有一个来自 Great British Baking Show 的挑战 DataFrame。 欢迎下载数据集:
pd.read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2022/2022-10-25/challenges.csv")
我已经清理了表格,现在有系列(1 到 10)、情节(6 到 10)、面包师(每个面包师的名字)和结果(面包师每周发生的事情(被淘汰 vs 仍然在展示))。 我正在寻找一种解决方案,允许我添加一个名为final_score
的新列,该列将列出每个系列的每个面包师的最终位置。
用英语我想做的是:
result == 'OUT'
,向记录面包师最终得分的 DF 添加一列。 每个赛季的第一个分数将等于步骤 1 中面包师的数量。然后我将面包师总数减 1。例如,第 1 季的面包师人数是 10。在第 1 集中,Lea 和 Mark 都被淘汰了,所以我希望他们两人的“final_score”都为 10。 在第 2 集中,A.netha 和 Louise 都被淘汰了,所以我希望他们的分数是 8。
我一天中的大部分时间都花在了这个问题上,而且我很困惑。 我已经尝试了 window 函数、应用函数、列表理解,但我得到的最接近的粘贴在下面。 通过尝试 1,我知道问题出在: if df.result =='OUT':
。 我知道这是一个系列,但我已经尝试过.result.items()
、 result.all()
、 result.any()
, if df.loc[df.result] == 'OUT':
但似乎没有工作。
尝试 1
def final_score(df):
#count the number of bakers per season
baker_count = df.groupby('series')['baker'].nunique()
#for each season
for s in df.series:
#create a interable that counts the number of bakers that have been eliminated. Start at 0
bakers_out = 0
bakers_remaining = baker_count[int(s)]
#for each season
for e in df.episode:
#does result say OUT for each contestant?
if df.result =='OUT':
df['final_score'] = bakers_remaining
#if so, then we'll add +1 to our bakers_out iterator.
bakers_out +=1
#set the final score category to our baker_count iterator
df['final_score'] = bakers_remaining
#subtract the number of bakers left by the amount we just lost
bakers_remaining -= bakers_out
else:
next
return df
尝试 2 不是关于我创建一个新的 dataframe,而是试图解决这个问题并将我想要的 output 打印到控制台。 这非常接近,但我希望最终结果是一个密集的得分,所以在第 1 系列第 1 集中出局的两个面包师应该都排在第 10 位,而下周出局的两个面包师应该都排在第 8 位地方。
baker_count = df.groupby('series')['baker'].nunique()
#for each series
for s in df.series.unique():
bakers_out = 0
bakers_remaining = baker_count[int(s)]
#for each episode
for e in df.episode.unique():
#create a list of results
data_results = list(df[(df.series==s) & (df.episode==e)].result)
for dr in data_results:
if dr =='OUT':
bakers_out += 1
print (s,e,dr,';final place:',bakers_remaining,';bakers out:',bakers_out)
else:
print (s,e,dr,'--')
bakers_remaining -= 1
Snippet of the result
1.0 1.0 IN --
1.0 1.0 IN --
1.0 1.0 IN --
1.0 1.0 IN --
1.0 1.0 IN --
1.0 1.0 OUT ;final place: 10 ;bakers out: 1
1.0 1.0 OUT ;final place: 10 ;bakers out: 2
1.0 2.0 IN --
1.0 2.0 IN --
1.0 2.0 IN --
1.0 2.0 IN --
1.0 2.0 IN --
1.0 2.0 IN --
1.0 2.0 OUT ;final place: 9 ;bakers out: 3
1.0 2.0 OUT ;final place: 9 ;bakers out: 4
谢谢大家,请让我知道我应该提供哪些其他信息。
您可以尝试以下操作( df
您的数据框):
m = df["result"].eq("OUT")
df["final_score"] = (
df.groupby("series")["baker"].transform("nunique")
- df[m].groupby("series")["baker"].cumcount()
)
df["final_score"] = df[m].groupby(["series", "episode"])["final_score"].transform("max")
前两个赛季的结果(并非所有列):
print(df[m & df["series"].isin([1, 2])])
series episode baker result final_score
8 1 1 Lea OUT 10.0
9 1 1 Mark OUT 10.0
16 1 2 Annetha OUT 8.0
17 1 2 Louise OUT 8.0
25 1 3 Jonathan OUT 6.0
34 1 4 David OUT 5.0
43 1 5 Jasminder OUT 4.0
70 2 1 Keith OUT 12.0
81 2 2 Simon OUT 11.0
91 2 3 Ian OUT 10.0
92 2 3 Urvashi OUT 10.0
101 2 4 Ben OUT 8.0
112 2 5 Jason OUT 7.0
113 2 5 Robert OUT 7.0
123 2 6 Yasmin OUT 5.0
135 2 7 Janet OUT 4.0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.