#python #pandas #pandas-groupby
#python #pandas #pandas-groupby
Вопрос:
У меня есть файл из SAP, который был не самым красивым при работе с данными. Итак, используя series.str.contains()
и логические маски, мне удалось сузить круг до фрейма данных, который выглядит следующим образом:
0 1
0 SUB 123
1 CAT SKU
2 CODE 1000123
3 CODE 1000234
4 SUB 456
5 CAT LIQ
6 CODE1 1000345
7 CODE1 1000534
8 CODE1 1000433
Я ищу способ, с помощью которого я мог бы разделить каждую из них SUB
на новую запись, как показано ниже:
print(expected_df)
SUB CAT CODE CODE1
0 123 SKU 1000123.0 NaN
1 123 SKU 1000234.0 NaN
2 456 LIQ NaN 1000345.0
3 456 LIQ NaN 1000534.0
4 456 LIQ NaN 1000433.0
Кажется, я просто не могу пройти этот шаг. Однако эта строка:
df[0].eq('SUB').cumsum()
помогает разделить группы и при необходимости может использоваться как вспомогательный ряд.
Любая помощь в транспонировании данных, как показано, была бы действительно оценена.
Спасибо.
Комментарии:
1. Всегда ли есть один
CAT
наSUB
?2. @Jondiedoop спасибо, что взглянули, да, на каждый сабвуфер есть только CAT. По сути, это похоже на категорию. 🙂
Ответ №1:
Вы можете попробовать использовать df.pivot
, за которым следуют .ffill(),bfill() для конкретных строк группы столбцов «SUB».
df1 = df.pivot(columns='0')
df1.columns = df1.columns.map(lambda x: x[1])
df1.SUB = df1.SUB.ffill()
df1.groupby('SUB').ffill().groupby('SUB').bfill().drop_duplicates()
#5.89 ms ± 1.84 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
# as time constraints, without use of lambda operation
#df1.groupby(df1.SUB.ffill()).apply(lambda x: x.ffill().bfill()).drop_duplicates()
#16 ms ± 1.06 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
Выход:
SUB CAT CODE CODE1 SUB
2 123 SKU 1000123 NaN 123
3 123 SKU 1000234 NaN 123
6 456 LIQ NaN 1000345 456
7 456 LIQ NaN 1000534 456
8 456 LIQ NaN 1000433 456
Ответ №2:
IIUC,
df.set_index('col1').groupby(df.col1.eq('SUB').cumsum().values).apply(lambda s: pd.DataFrame({
'SUB': s.loc['SUB'].item(),
'CAT': s.loc['CAT'].item(),
s.index[2]: s.loc[s.index[2]].col2.tolist()
})).reset_index(drop=True)
Выводит
SUB CAT CODE CODE1
0 123 SKU 1000123 NaN
1 123 SKU 1000234 NaN
2 456 LIQ NaN 1000345
3 456 LIQ NaN 1000534
4 456 LIQ NaN 1000433
Однако это похоже на проблему XY. Может быть, стоит взглянуть на то, как вы в конечном итоге получили это df
в первую очередь
Ответ №3:
IIUC
l=[y.set_index('0').T.set_index(['SUB','CAT']).stack() for x , y in df.groupby(df['0'].eq('SUB').cumsum())]
s=pd.concat(l).to_frame('v')
s.assign(key=s.groupby(level=[0,1,2]).cumcount()).set_index('key',append=True).unstack(2)
v
0 CODE CODE1
SUB CAT key
123 SKU 0 1000123 NaN
1 1000234 NaN
456 LIQ 0 NaN 1000345
1 NaN 1000534
2 NaN 1000433