#python #pandas #numpy
Вопрос:
Мой начальный фрейм данных pandas выглядит следующим образом:
df = pd.DataFrame(np.array([[999,888,1,0], [988,899,2,0], [981,821,3,0],[721,789,4,1],[723,745,5,1],[444,432,6,2],[423,412,7,2],[423,455,8,2],[478,432,9,2]]), columns=['a', 'b', 'c', 'id']) gt;gt;gt;df a b c id 999 888 1 0 988 899 2 0 981 821 3 0 721 789 4 1 723 745 5 1 444 432 6 2 423 412 7 2 423 455 8 2 478 432 9 2
Теперь я хочу создать новый фрейм данных со следующей структурой:
0 1 2 3 4 5 999 988 888 899 1 2 721 723 789 745 4 5 444 423 432 412 6 7
Так что на самом деле я просто хочу получить первые два значения каждого идентификатора и каждого столбца (a,b,c). Пример: первая строка -gt; col a: 999, 988 col b: 888, 899 col c: 1, 2
Редактировать: Благодаря Коррелиану я использую следующий код:
size = 3 data = df.groupby('id').head(2).melt('id').sort_values(by=['id', 'variable'])['value'] out = pd.DataFrame(data.values.reshape((size, -1)))
Ответ №1:
Вычислите количество значений id
, чтобы получить размер (количество уникальных идентификаторов, здесь 3) и наименьшее количество (здесь 2 для идентификатора=1). Сгруппируйте id
и сохраните первую count
строку для каждой используемой группы head
.
Затем используйте melt
для выравнивания фрейма данных и сортировки его по id
. Наконец, измените свой фрейм данных в соответствии с size
переменной и создайте новый фрейм данных:
size, count = df.value_counts('id').agg(['size', 'min']) data = df.groupby('id').head(count).melt('id').sort_values('id')['value'] out = pd.DataFrame(data.values.reshape((size, -1))) print(out) # Output: 0 1 2 3 0 999 988 888 899 1 721 723 789 745 2 444 423 432 412
Обновить
Я изменил свой начальный фрейм данных на 3 столбца (a,b,c) см. Мой первоначальный вопрос. Как я должен изменить ваш код?
size, count = df.value_counts('id').agg(['size', 'min']) m = df.groupby('id').head(count).iloc[:, :-1].values df = pd.DataFrame(np.hstack(m.T.reshape(-1, size, count))) print(df) # Output: 0 1 2 3 4 5 0 999 988 888 899 1 2 1 721 723 789 745 4 5 2 444 423 432 412 6 7
Комментарии:
1. Я изменил свой начальный фрейм данных на 3 столбца (a,b,c) см. Мой первоначальный вопрос. Как я должен изменить ваш код? Я пытался, но не преуспел..
Ответ №2:
Этого можно было бы достичь следующим образом:
pd.DataFrame(df.groupby("id").head(2).set_index('id').values.flatten().reshape((3,4)))
Редактировать
Новым примером может быть:
pd.DataFrame(df.groupby("id").head(2).set_index('id').values.flatten().reshape((3,6)))[[0,1,3,4,2,5]]
С помощью этого метода вы должны изменить порядок столбцов, чтобы получить желаемый результат.
Комментарии:
1. Ваш ответ абсолютно верен (для двух столбцов). Однако я изменил свой исходный фрейм данных на 3 столбца (a,b,c). См. Мой первоначальный вопрос. Как я должен изменить ваш код? Я пытался, но безуспешно..