Вам не нужно зацикливаться, но вам нужно «растопить» ваш фрейм данных перед операцией группировки.
Итак, начиная с:
from io import StringIO
import pandas
f = StringIO("""\
ID,col_1,col_2,col_3,Date
1,,20,40,1/1/2018
1,10,,,1/2/2018
1,50,,60,1/3/2018
3,40,10,90,1/1/2018
4,,80,80,1/1/2018
""")
df = pandas.read_csv(f)
Вы можете затем:
print(
df.melt(id_vars=['ID', 'Date'], value_vars=['col_1', 'col_2', 'col_3'], value_name='first')
.groupby(by=['ID', 'variable'])
.first()
.unstack(level='variable')
)
Что дает вам:
Date first
variable col_1 col_2 col_3 col_1 col_2 col_3
ID
1 1/1/2018 1/1/2018 1/1/2018 10.0 20.0 40.0
3 1/1/2018 1/1/2018 1/1/2018 40.0 10.0 90.0
4 1/1/2018 1/1/2018 1/1/2018 NaN 80.0 80.0
Столбцы многоуровневые, так что вы можете их немного полировать, если хотите:
def flatten_columns(df, sep='_'):
newcols = [sep.join(_) for _ in df.columns]
return df.set_axis(newcols, axis='columns', inplace=False)
print(
df.melt(id_vars=['ID', 'Date'], value_vars=['col_1', 'col_2', 'col_3'], value_name='first')
.groupby(by=['ID', 'variable'])
.first()
.unstack(level='variable')
.sort_index(level='variable', axis='columns')
.pipe(flatten_columns)
)
Что дает вам что-то с не совсем тем же порядком столбцов, что и в вашем примере, но это настолько близко, насколько мне кажется, сделать это.
Date_col_1 first_col_1 Date_col_2 first_col_2 Date_col_3 first_col_3
ID
1 1/1/2018 10.0 1/1/2018 20.0 1/1/2018 40.0
3 1/1/2018 40.0 1/1/2018 10.0 1/1/2018 90.0
4 1/1/2018 NaN 1/1/2018 80.0 1/1/2018 80.0