按字段填充以前的值 - 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'))
我正在尝试用特定子集的前一行的值(满足条件时)填充新列(上一次)中的每一行。问题是,如果我中断内核并检查值,就可以了。但是如果它运行到最后,那么新列中的所有行都用 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'))