pandas преобразует фрейм данных в сводную таблицу, где индекс — это значения сортировки

#python #pandas #dataframe #pandas-groupby

#python #pandas #фрейм данных #pandas-groupby

Вопрос:

у меня есть следующий фрейм данных:

    site   height_id  height_meters
0  9      c3         24
1  9      c2         30
2  9      c1         36
3  3      c0         18
4  3      bf         24
5  3      be         30
6  4      10         18
7  4      0f         24
8  4      0e         30
 

я хочу преобразовать его в следующее: индексы этого столбца — это значения ‘site’, а значения — ‘height_meters’, и я хочу, чтобы он индексировался по порядку значений (я посмотрел в Интернете и не нашел ничего похожего … безуспешно пытался сгруппировать и создать сводную таблицу):

    9   3   4
0  24  18  18
1  30  24  24
2  36  30  24
 

разрыв между числами не требуется …
вот df

 my_df = pd.DataFrame(dict(
    site=[9, 9, 9, 3, 3, 3, 4, 4, 4],
    height_id='c3,c2,c1,c0,bf,be,10,0f,0e'.split(','),
    height_meters=[24, 30, 36, 18, 24, 30, 18, 24, 30]
))
 

Ответ №1:

Вы можете использовать GroupBy.cumcount для счетчика столбца site :

 print (my_df.groupby('site').cumcount())

0    0
1    1
2    2
3    0
4    1
5    2
6    0
7    1
8    2
dtype: int64
 

Вы можете преобразовать его в index site столбец with и изменить его с помощью Series.unstack :

 df = my_df.set_index([my_df.groupby('site').cumcount(), 'site'])['height_meters'].unstack()
print (df)
site   3   4   9
0     18  18  24
1     24  24  30
2     30  30  36
 

Аналогичное решение с DataFrame.pivot и столбцом, созданным cumcount :

 df = my_df.assign(new=my_df.groupby('site').cumcount()).pivot('new','site','height_meters')
print (df)
site   3   4   9
new             
0     18  18  24
1     24  24  30
2     30  30  36
 

Если порядок важен, добавьте DataFrame.reindex уникальные значения столбца site :

 df = (my_df.set_index([my_df.groupby('site').cumcount(), 'site'])['height_meters']
           .unstack()
           .reindex(my_df['site'].unique(), axis=1))
print (df)
site   9   3   4
0     24  18  18
1     30  24  24
2     36  30  30
 

Последнее для столбцов remove site ( new ) и имен индексов возможно использовать DataFrame.rename_axis :

 df = df.rename_axis(index=None, columns=None)
print (df)
    3   4   9
0  18  18  24
1  24  24  30
2  30  30  36
 

Комментарии:

1. люблю тебя, чувак!!! спасибо, не могли бы вы добавить небольшое объяснение для cumcount и unstack?

2. @ombk — не я, панды 😉

3. чувак, я действительно ценю тебя, большое тебе спасибо, ты делаешь мир намного лучше! (для тех, кто не знает, почему я так волнуюсь, потому что я использую @jezreal answers в сообществе stackoverflow!)