pandas Python DataFrames -基于多个条件创建新列所需的帮助

92dk7w1h  于 2022-12-02  发布在  Python
关注(0)|答案(1)|浏览(115)

我有一个来自英国烘焙展的挑战数据框。请随时下载数据集:

pd.read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2022/2022-10-25/challenges.csv")

我已经清理了表,现在有了系列的列(1到10),(6到10),贝克(各烘焙师的姓名),和结果(面包师每周都发生了什么(被淘汰VS还在节目中))。我正在寻找一个解决方案,允许我添加一个新的列称为final_score,将列出每个系列的每个面包师的最终位置。
用英语来说,我想做的是:
1.计算每个系列的面包机的唯一数量。
1.对于每个系列,对于每一集,如果result == 'OUT',在DF中增加一列,记录面包师的最终得分。每个季节的第一个得分将等于步骤1中面包师的总数。然后我将面包师总数减去1。
例如,第1季的面包师人数是10。在第1集中,莱亚和Mark都被淘汰了,所以我希望他们的“final_score”都是10。在第2集中,Annetha和Louise都被淘汰了,所以我希望他们的得分是8。
我花了一整天的时间来解决这个问题,但我还是被困在了这里。我试过窗口函数、应用函数、列表解析,但最接近的是下面的粘贴。通过第一次尝试,我知道问题出在: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

第二次尝试并不是要我创建一个新的 Dataframe ,而是尝试解决这个问题,并在控制台上打印出我想要的输出。这是非常接近的,但我希望最终的结果是一个密集的得分,所以在系列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

谢谢大家,请让我知道我应该提供什么其他信息。

57hvy0tb

57hvy0tb1#

您可以尝试以下操作(df您的 Dataframe ):

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")

前2个季度的结果(并非所有列):
第一次

相关问题