Je souhaite ajouter une ligne à la fin d'un dataframe qui peut être groupé par une variable.
Mon dataframe ressemble à ceci:
df = pd.DataFrame(columns = operacionales.columns) val = range(1, 22223) for x in val: test = operacionales.loc[operacionales['ID'] == x] li = [test.ID.iloc[0], test.Name1.iloc[0], test.Name2.iloc[0], test.PointB.iloc[-1], '-', test.Var1.max() + 1, 0] t = pd.DataFrame(li).T t.columns = test.columns test2 = test.append(t) df = df.append(test2)
Et ce que je veux, c'est ajouter une ligne à la fin de chaque catégorie comme défini par ID
:
|ID | Name1 | Name2 | PointA | PointB | Var1 | Var2 | | 1 | AAA | zzz | ABC | BCD | 1 | 5 | | 1 | AAA | zzz | BCD | CDE | 2 | 5 | | 1 | AAA | zzz | CDE | DEF | 3 | 5 | | 1 | AAA | zzz | DEF | --- | 4 | 0 | | 2 | BBB | yyy | STU | TUV | 1 | 6 | | 2 | BBB | yyy | TUV | UVW | 2 | 6 | | 2 | BBB | yyy | UVW | VWX | 3 | 6 | | 2 | BBB | yyy | VWX | WXY | 4 | 6 | | 2 | BBB | yyy | WXY | --- | 5 | 0 |
J'ai essayé: (mon df d'origine s'appelle operacionales
)
|ID | Name1 | Name2 | PointA | PointB | Var1 | Var2 | | 1 | AAA | zzz | ABC | BCD | 1 | 5 | | 1 | AAA | zzz | BCD | CDE | 2 | 5 | | 1 | AAA | zzz | CDE | DEF | 3 | 5 | | 2 | BBB | yyy | STU | TUV | 1 | 6 | | 2 | BBB | yyy | TUV | UVW | 2 | 6 | | 2 | BBB | yyy | UVW | VWX | 3 | 6 | | 2 | BBB | yyy | VWX | WXY | 4 | 6 |
mais j'ai un "IndexError: l'indexeur de position unique est hors limites "
J'ai essayé la même chose mais avec l'index [-1]
au lieu de [0]
dans le code et le résultat est le même.
Comme vous peut voir la ligne que je veux ajouter est exactement la même que les autres lignes du groupe, à l'exception de:
1. PointA
(que je veux être la dernière valeur de la variable PointB
),
2. PointB
(que je souhaite définir sur "---"),
3. Var1
(que je veux être +1 de la dernière valeur du groupe), et
4. Point2
(que je veux mettre à 0).
J'ai trouvé ceci ( ajoutez des lignes à un Pandas groupby object ) mais cela ne m'a pas vraiment aidé.
Toute aide serait appréciée.
4 Réponses :
def update_method(series): last_row = series.iloc[-1] new_row = last_row new_row['PointA'] = last_row['PointA'] new_row['PointB'] = '---' new_row['Var1'] = last_row['Var1']+1 series = series.append(new_row) return series new_df = df.groupby('Name1').apply(update_method)
C'est exactement ce dont j'avais besoin! Merci beaucoup.
IIUC
appenddf=df.groupby('ID').tail(1) appenddf=appenddf.drop('PointA',1).rename(columns={'PointB':'PointA'}).assign(Var1=appenddf.Var1+1) df=pd.concat([df,appenddf],sort=True).sort_index() df Out[232]: ID Name1 Name2 PointA PointB Var1 Var2 0 1 AAA zzz ABC BCD 1 5 1 1 AAA zzz BCD CDE 2 5 2 1 AAA zzz CDE DEF 3 5 2 1 AAA zzz DEF NaN 4 5 3 2 BBB yyy STU TUV 1 6 4 2 BBB yyy TUV UVW 2 6 5 2 BBB yyy UVW VWX 3 6 6 2 BBB yyy VWX WXY 4 6 6 2 BBB yyy WXY NaN 5 6
Vous pouvez utiliser groupby / apply:
def append_column_to_group(group): result = group result = result.append({'ID': 1, 'Name1': group.iloc[0].Name1, 'Name2': group.iloc[0].Name2, 'PointA': group.iloc[-1].PointB, 'PointB': '---', 'Var1': group.iloc[-1].Var1 + 1, 'Var2': 0}, ignore_index=True) return result df.groupby('Name1').apply(append_column_to_group)
Voici ce que je ferais:
t = df.groupby('ID', as_index=False).last() t[['PointA', 'PointB', 'Var1', 'Var2']] = np.column_stack([t.PointB, ['---']*2, t.Var1+1, [0]*2]) pd.concat([df, t], ignore_index=True).sort_values('ID') Out[121]: ID Name1 Name2 PointA PointB Var1 Var2 0 1 AAA zzz ABC BCD 1 5 1 1 AAA zzz BCD CDE 2 5 2 1 AAA zzz CDE DEF 3 5 7 1 AAA zzz DEF --- 4 0 3 2 BBB yyy STU TUV 1 6 4 2 BBB yyy TUV UVW 2 6 5 2 BBB yyy UVW VWX 3 6 6 2 BBB yyy VWX WXY 4 6 8 2 BBB yyy WXY --- 5 0