用最大值加1递增地替换NaN值

5
我有一个数据框,看起来像这样:

enter image description here

我想通过从该年的最大值继续填充NaN(即根据每年的最大值逐步增加)。
这就是我想实现的:

enter image description here

我知道如何将此应用于每个年份,方法是在for循环中为每个年份创建单独的数据框,然后将它们合并。
#data
d = {'year': {0: 2016,
  1: 2016,
  2: 2016,
  3: 2016,
  4: 2017,
  5: 2017,
  6: 2017,
  7: 2017,
  8: 2018,
  9: 2018,
  10: 2018},
 'id': {0: 1015.0,
  1: 1016.0,
  2: nan,
  3: nan,
  4: 1035.0,
  5: 1036.0,
  6: nan,
  7: nan,
  8: 1005.0,
  9: nan,
  10: nan}}

# list of years
years = [2016,2017,2018]

# create dataframe    
df = pd.DataFrame(d)

# create list that I will append data frames too
l = []

for x in years:
    # create a dataframe for each year
    df1 = df[df['year']==x].copy()
    # fill nans with max value plus 1
    df1['id'] = df1['id'].fillna(lambda x: x['id'].max() + 1)
    # add dataframe to list
    l.append(df1)
# concat list of dataframes
final = pd.concat(l)

这将nans替换为以下文本:

function at 0x000002201F43CB70

我还尝试在我的for循环中使用以下内容:

df1['id'] = df1['id'].apply(lambda x: x['id'].fillna(x['id'].max() +1))

但是我遇到了一个错误:
TypeError: 'float' object is not subscriptable

df.interpolate 可能有所帮助……只是我还没有弄清如何按年份分组使用它。 - Will
@Will 你可以使用这个答案与df.interpolate和group by结合使用。但我不确定如何在插值时实现最大值+1。 - Lala La
1个回答

3

您可以使用df.iterrows()遍历行,使用df.loc[]设置缺失的"id"值:

for index, row in df.iterrows():
    if row['id'] > 0 : continue
    df.loc[index,"id"] = df[df['year']==row['year']]['id'].max() +1

编辑

更好的检查row ['id']是否不为空的方法是:

    if pd.notnull(row['id']): ...

这会将每行的值加1,包括已经存在的数值。我不会点踩因为你很接近了! - d_kennetz
有一个if语句可以避免这种情况 :) - Sebastien D
我在他的数据上运行了你的代码,返回了这个结果 :P。 - d_kennetz
感谢指出这一点。由于某种原因,我很难处理 np.nan 的条件。已用 null 值代替它。 - Sebastien D
只要数据框按年份排序,这个应该就可以工作了。 - Will

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接