Mam następujący rodzaj ramki danych.

Id   Name    Exam    Result     Exam        Result
1     Bob    Maths     10      Physics       9
2     Mar    ML        8       Chemistry     10       

Chciałbym usunąć zduplikowane kolumny i dodać ich wartość do odpowiednich wierszy. Coś poniżej

Id   Name   Exam     Result
1    Bob    Maths      10
1    Bob    Physics    9
2    Mar     ML        8
2    Mar   Chemistry   10

Czy można to zrobić w Pythonie?

Każda pomoc jest mile widziana!

0
user6053895 26 marzec 2020, 10:45

2 odpowiedzi

Najlepsza odpowiedź

Najpierw utwórz MultiIndex według pierwszych kolumn, które nie są zduplikowane przez DataFrame.set_index, a następnie utwórz MultiIndex in columns przez licznik nazw duplikatów z GroupBy.cumcount pracując z seriami, więc Index.to_series i ostatnia zmiana kształtu przez DataFrame.stack z DataFrame.reset_index, aby usunąć poziom pomocnika, a następnie MultiIndex do kolumn:

df = df.set_index(['Id','Name'])
s = df.columns.to_series()
df.columns = [s, s.groupby(s).cumcount()]
df = df.stack().reset_index(level=2, drop=True).reset_index()
print (df)
   Id Name       Exam  Result
0   1  Bob      Maths      10
1   1  Bob    Physics       9
2   2  Mar         ML       8
3   2  Mar  Chemistry      10
2
jezrael 26 marzec 2020, 07:51

To jest alternatywa dla pand melt:

#flip table into long format    
(df.melt(['Id','Name'])
 #sort by Id so that result follows immediately after Exam
 .sort_values('Id')
 #create new column on rows that have result in the variable column
 .assign(Result=lambda x: x.loc[x['variable']=="Result",'value'])
 .bfill()
 #get rid of rows that contain 'result' in variable column
 .query('variable != "Result"')
 .drop(['variable'],axis=1)
 .rename(columns={'value':'Exam'})
 )

    Id  Name    Exam       Result
0   1   Bob     Maths       10
4   1   Bob     Physics      9
1   2   Mar     ML           8
5   2   Mar    Chemistry    10

Alternatywnie, dla zabawy:

df = df.set_index(['Id','Name'])

#get boolean of duplicated columns
dupes = df.columns.duplicated()

#concatenate first columns and their duplicates
pd.concat([df.loc[:,~dupes],
           df.loc[:,dupes]
          ]).sort_index()
0
sammywemmy 26 marzec 2020, 08:38