#python #python-3.x #pandas #dataframe
Вопрос:
Допустим, у меня есть фрейм данных следующего вида:
Имя | Время работы в 1-м часу | Время, потраченное впустую за 1 час | Время работы во 2-м часу | Время, потраченное впустую за 2 часа |
---|---|---|---|---|
фу | 45 | 15 | 40 | 20 |
бар | 35 | 25 | 55 | 5 |
баз | 50 | 10 | 45 | 15 |
Я хочу использовать расплав в столбцах 1-го часа и столбцах 2-го часа, чтобы это выглядело так:
Имя | Номер часа | Время, отработанное в отделе кадров | Время, потраченное впустую в отдел кадров |
---|---|---|---|
фу | 1 | 45 | 15 |
фу | 2 | 40 | 20 |
бар | 1 | 35 | 25 |
бар | 2 | 55 | 5 |
баз | 1 | 50 | 10 |
баз | 2 | 45 | 15 |
Как бы я сгруппировал «Время, затраченное в 1-й час» и «Время, потраченное впустую в 1-й час» вместе, чтобы я мог объединить их в один ряд?
Ответ №1:
Вы можете использовать:
df1 = df.set_index('Name')
df1.columns = df1.columns.str.split('in', expand=True)
df2 = (df1.stack()
.sort_index(axis=1, ascending=False)
.rename_axis(index=['Name', 'Hour number'])
.add_suffix('in the hr')
.reset_index()
)
df2['Hour number'] = df2['Hour number'].str.extract(r'(d )')
Результат:
print(df2)
Name Hour number Time worked in the hr Time wasted in the hr
0 foo 1 45 15
1 foo 2 40 20
2 bar 1 35 25
3 bar 2 55 5
4 baz 1 50 10
5 baz 2 45 15
Комментарии:
1. Спасибо! Я не уверен, что должна делать последняя строка, что должен делать str.extract в этом случае?
2. @crysoar Последняя строка предназначена для извлечения номера часа из текста
1st
и2nd
т. Д. Если вы выполните приведенные выше коды шаг за шагом без последней строки, вы увидите промежуточный результатHour number
удержания1st hr
,2nd hr
. Нам нужно навести порядок и получить только номер.
Ответ №2:
Что-то вроде:
import numpy as np
df = df.set_index('Name')
df.columns = pd.MultiIndex.from_arrays([np.repeat([1,2], len(df.columns)//2), np.tile(['worked', 'wasted'], len(df.columns)//2)])
df.stack(level=0)
nb. Я не мог проверить код
Ответ №3:
Вы можете выполнить всю обработку текста в столбцах перед изменением формы; чем меньше строк для работы, тем лучше/быстрее может быть ваш код:
Установить Name
в качестве индекса:
df = df.set_index('Name')
Извлеките числа и установите expand=False
, чтобы они оставались в качестве индекса:
numbers = df.columns.str.extract(r"(d)", expand=False).rename("Hour Number")
Замените цифры на the
:
no_numbers = df.columns.str.replace("d.{2}", "the", regex=True)
Создайте столбец с несколькими индексами:
df.columns = pd.MultiIndex.from_arrays([numbers, no_numbers])
Сложите столбцы в стопку и сбросьте индекс:
df.stack('Hour Number').reset_index()
Name Hour Number Time wasted in the hr Time worked in the hr
0 foo 1 15 45
1 foo 2 20 40
2 bar 1 25 35
3 bar 2 5 55
4 baz 1 10 50
5 baz 2 15 45