按字段填充以前的值 - Pandas 应用函数填充 None

Filling previous value by field - Pandas apply function filling None

我正在尝试用特定子集的前一行的值(满足条件时)填充新列(上一次)中的每一行。问题是,如果我中断内核并检查值,就可以了。但是如果它运行到最后,那么新列中的所有行都用 None 填充。如果前一行不存在,那么我将用第一个值填充它。

Name       First round  Previous time
Runner 1   2            2
Runner 2   5            5
Runner 3   5            5
Runner 1   6            2
Runner 2   8            5
Runner 3   4            5
Runner 1   2            6
Runner 2   5            8
Runner 3   5            4

我尝试了什么:

df.insert(column = "Previous time", value = 999)

def fce(arg):
    runner= arg[0]
    stat = arg[1]

    if stat == 999:
        # I used this to avoid filling all rows in a new column again for the same runner
        first = df.loc[df['Name'] == runner,"First round"].iloc[0]
        df.loc[df['Name'] == runner,"Previous time"] = df.loc[df['Name'] == runner]["First round"].shift(1, fill_value = first)

df["Previous time"] = df[['Name', "Previous time"]].apply(fce, axis=1)

问题是你的函数fce returns None每一行,所以术语df[['Name', "Previous time"]].apply(fce, axis=1)产生的系列是[=12的系列=].

也就是说,您 需要 到 return 填充此位置的值。不幸的是,这是不可能的,因为那时你需要知道你已经计算了哪些指数。

更好的方法是使用 groupby。这是一种更自然的方式,因为您想对每个组执行一个操作。如果您在 groupby 之后使用 apply 并使用 return 一个系列,那么您实际上为每一行定义了一个值。请记住删除 groupby 添加的额外索引 "Name"

def fce(g): 
    first = g["First round"].iloc[0] 
    return g["First round"].shift(1, fill_value=first) 

df["Previous time"] == df.groupby("Name").apply(fce).reset_index("Name", drop=True)

非常感谢。请你再回答我一个问题好吗?如果我想return根据特定跑步者在比赛前的睡眠时间计算所有轮次的平均值,它如何与多列分组一起工作。

Expected output:
    Name       First round  Sleep before race Mean
    Runner 1   2            8                 4 
    Runner 2   5            7                 6 
    Runner 3   5            8                 5
    Runner 1   6            8                 4
    Runner 2   8            7                 6
    Runner 3   4            9                 4,5
    Runner 1   2            9                 2
    Runner 2   5            7                 6
    Runner 3   5            9                 4,5

这对我不起作用。

def last_season(g):
    aa = g["First round"].mean()


df["Mean"] = df.groupby(["Name", "Sleep before race"]).apply(g).reset_index(["Name", "Sleep before race"], drop=True)

对每个名称进行管道分组,并用原始系列填充缺失值。

df['Previous time'] = (df.groupby('Name')['First round']
                         .shift()
                         .fillna(df['First round'], downcast='infer'))