问题描述
我需要根据 groupby 类型插入基于列周的行,在某些情况下,我在不同位置的数据框中间缺少周,我想插入行以填充缺失的行作为副本最后一个现有行,在这种情况下,第 7 周的副本填充第 8 周和第 9 周,第 11 周的副本填充第 12、13 和 14 周的行:在此表上,您可以看到从第 7 周到第 10 周的跳转从 11 点到 15 点:
下面是我的代码,它只插入一行,我很困惑为什么:
def middle_values(final : DataFrame) -> DataFrame:
finaltemp= pd.DataFrame()
out= pd.DataFrame()
for i in range(0,len(final)):
for f in range(1,52,1):
if final.iat[i,8]== f and final.iat[i-1,8] != f-1 :
if final.iat[i,8] > final.iat[i-1,8] and final.iat[i,8] != (final.iat[i-1,8] - 1):
line = final.iloc[i-1]
c1 = final[0:i]
c2 = final[i:]
c1.loc[i]=line
concatinated = pd.concat([c1,c2])
concatinated.reset_index(inplace=True)
concatinated.iat[i,11] = concatinated.iat[i-1,11]
concatinated.iat[i,9]= f-1
finaltemp = finaltemp.append(concatinated)
if 'type' in finaltemp.columns:
for name,groups in finaltemp.groupby(["type"]):
weeks = range(groups['week'].min(),groups['week'].max()+1)
out = out.append(pd.merge(finaltemp,pd.Series(weeks,name='week'),how='right').ffill())
out.drop_duplicates(subset=['project','week'],keep = 'first',inplace=True)
out.drop_duplicates(inplace = True)
out.sort_values(["Budget: Budget Name","Budget Week"],ascending = (False,True),inplace=True)
out.drop(['level_0'],axis = 1,inplace=True)
out.reset_index(inplace=True)
out.drop(['level_0'],inplace=True)
return out
else :
return final
解决方法
对于您问题的第一部分。假设我们有一个如下所示的数据框:
df = DataFrame({"project":[1,1,2,2],"week":[1,3,4,4],"value":[12,22,18,17,23]})
我们可以创建一个新的多索引来获取我们需要的额外行
new_index = pd.MultiIndex.from_arrays([sorted([i for i in df['project'].unique()]*52),[i for i in np.arange(1,53,1)]*df['project'].unique().shape[0]],names=['project','week'])
然后我们可以应用这个索引来获取你需要的新数据框,新行中有空格
df = df.set_index(['project','week']).reindex(new_index).reset_index().sort_values(['project','week'])
然后,您需要使用 groupby 和转换应用正向填充(使用填充)或反向填充(使用 bfill)以获取所需行中的所需值。