#python #pandas #pivot #pandas-groupby #reshape
Вопрос:
У меня есть фрейм данных, который выглядит примерно так
df_input = pd.DataFrame({'datatype':['IN','IN','EX','EX','IN','IN','EX','EX'], 'Time': [0,0,0,0,1,1,1,1], 'filetype': ['img','txt','img','txt','img','txt','img','txt']}, index=['PMSN01001','PMSN01001','PMSN01001','PMSN01001','PMSN01001','PMSN01001','PMSN01001','PMSN01001'])
print(df_input)
id datatype Time filetype
PMSN01001 IN 0 img
PMSN01001 IN 0 txt
PMSN01001 EX 0 img
PMSN01001 EX 0 txt
PMSN01001 IN 1 img
PMSN01001 IN 1 txt
PMSN01001 EX 1 img
PMSN01001 EX 1 txt
Я хочу изменить формат фрейма данных с длинного на широкий, как показано ниже. Я видел много решений в сообществе, но немногие имеют дело с настройкой имени столбца, интуитивно понятной и достаточно простой для понимания новичками вроде меня. Я знаю, что должен использовать .Как-то сверните, но я борюсь с двумя вещами: простым способом настройки имени столбца и тем, как настроить мультииндекс(составной первичный ключ)
ничего не стоящий, для каждого идентификатора, с комбинацией [‘тип данных’, ‘Время’, ‘тип файла’], может составлять до 8 записей данных(2x2x2). Поэтому поворотные столбцы также должны соответствующим образом отражать … я думаю..
df_output = pd.DataFrame({'datatype_time0':['IN'], 'Time_time0': [0], 'filetype_time0': ['img'],'filetype2_time0':['txt'], 'datatype_time1':['EX'], 'Time_time1':[1], 'filetype_time1': ['img'],'filetype2_time1':['txt']}, index=['PMSN01001'])
df_output
datatype_time0 Time_time0 filetype_time0 filetype2_time0 datatype_time1 Time_time1 filetype_time1 filetype2_time1
PMSN01001 IN 0 img txt EX 1 img txt
Я открыт для любых способов переименования имен столбцов, если я могу отслеживать, какие значения принадлежат какому
Спасибо
Комментарии:
1. @jezrael, мне жаль, что я совершил огромную ошибку. проще говоря, один идентификатор может содержать до 8 записей, основанных на комбинации [«тип данных», «Время», «тип файла»]. Поэтому задача состоит в том, чтобы сделать их в широком формате. Я обновил контент, лучше всего
2. Хм, так нужно ли сначала удалять дубликаты?
3. если я правильно вас понял. сам идентификатор дублируется, но разве все они не составляют минимальную уникальную запись данных на основе комбинации [тип данных, время, тип файла] ?
4. Так нужно, как будто
x = df.groupby(['id', 'datatype']).agg(Time=('Time', 'first'), filetype1=('filetype', 'first'), filetype2=('filetype', 'last'))
это означает «первый и последнийfiletype
['id', 'datatype']
«? Ты уверен?5. я чувствую, что df.groupby ([«идентификатор», «тип данных», «Время», «тип файла»]) имеет больше смысла, потому что я использую id 3 ключа в качестве составного ключа priamry
Ответ №1:
Попробуйте использовать groupby
, cumcount
и pivot_table
:
x = df.groupby(['id', 'datatype']).agg(Time=('Time', 'first'), filetype1=('filetype', 'first'), filetype2=('filetype', 'last'))
x = x.assign(idx=x.groupby(level=0).cumcount() 1).reset_index().pivot_table(index=['id'], columns='idx',
values=['datatype', 'Time', 'filetype1', 'filetype2'], aggfunc='first')
x = x.sort_index(axis=1, level=1)
x = x.set_axis([f'{x}_{y}' for x,y in x.columns], axis=1).reset_index()
>>> x
id Time_1 datatype_1 filetype1_1 filetype2_1 Time_2 datatype_2 filetype1_2 filetype2_2
0 PMSN01001 1 EX img txt 0 IN img txt
>>>
Комментарии:
1. спасибо, ваше решение было полезным, но могу ли я спросить, почему это df.groupby ([«идентификатор», «тип данных»]) вместо df.groupby ([«идентификатор», «тип данных», «Время», «тип файла»])?
2. @WonChulChung Это потому, что именно эти столбцы делают разделение 🙂 и вы могли бы указать больше столбцов, но просто этих двух достаточно, чтобы определить разделение. Не стесняйтесь отмечать и озвучивать это, если вы считаете, что это полезно 🙂