#python #pandas
#python #pandas
Вопрос:
Итак, у меня есть pandas df, который выглядит следующим образом
где каждый столбец — это час дня, указанный в столбце даты. Я хотел бы повернуть этот df так, чтобы каждый час дня был отдельной строкой. Похоже на это
где было бы 24 строки для каждого часа каждой даты.
Я попытался использовать pd.melt, используя следующее
hourly_value = ['00:00','01:00','02:00','03:00','04:00','05:00','06:00','07:00','08:00','09:00','10:00','11:00','12:00']
df = df.melt(id_vars = ['DATE'], var_name = hourly_value, value_name = ('Hourly Precip'))
но продолжайте получать ошибку «Ошибка индекса: слишком много уровней: индекс имеет только 1 уровень, а не 2». Я также изучал использование df.pivot, но я начинаю думать, что мой df имеет формат, сильно отличающийся от большинства примеров.
Ответ №1:
Один из способов получить то, что вы хотите, — это:
-
Используется
.set_index('DATE')
для превращенияDATE
столбца в индекс. -
Используйте
.stack()
, чтобы также включить столбцы в индекс, создаваяMultiIndex
, где строка для каждой даты вставляется в качестве второго уровня в индексе. -
Используется
.reset_index()
для преобразования всех уровней индекса обратно в строки.
Следующий фрагмент иллюстрирует:
import numpy as np
import pandas as pd
dates = [f"1/{i}/2020" for i in range(1, 21)]
cols = ["DATE"] [str(i) ":00" for i in range(25)]
zeros = np.zeros((len(dates), len(cols) - 1))
data = list([[x] list(y) for x, y in zip(dates, zeros)])
df = pd.DataFrame(data=data, columns=cols)
df2 = (
df.set_index("DATE") # makes the DATE column the index
.stack() # stacks
.reset_index()
.rename(columns={"level_1": "Time", 0: "Value"})
)
print(df2.head())
Какие результаты:
DATE Time Value
0 1/1/2020 0:00 0.0
1 1/1/2020 1:00 0.0
2 1/1/2020 2:00 0.0
3 1/1/2020 3:00 0.0
4 1/1/2020 4:00 0.0
Комментарии:
1. Это именно то, что я пытался сделать. теперь, когда я вижу, что это возможно, как бы я это сделал, если бы у меня было 4 дополнительных столбца (я исключил их из исходного формата df), связанных с каждым часовым измерением? Я бы просто продолжил переименовывать с
.rename(columns = {'level_1':'Time',0:'Value', 1 :'Value 2 name',2:'Value 3 name'}
помощью и так далее?2.
.stack()
помещает все исходные столбцы в один столбец (тот, который назван0
), поэтому я не думаю, что это сработает для вашего последующего сценария. Если вы хотите, чтобы несколько значений для каждого часа были отдельными столбцами в конечном результате, вы можете попробовать разделить столбцы исходного фрейма данных, применив описанную выше процедуру к каждому отдельно, а затем объединить их обратно.3. да, именно так я начал заниматься последующим. спасибо, что подтвердили мои мысли по этому поводу
Ответ №2:
Попробуйте это :
pd.melt( df.reset_index(), id_vars=['DATE'], var_name='hour', value_name='Hourly Precip')
Комментарии:
1. df.reset_index — это то, что я искал. Я пытался использовать reset index = True, но из-за этого продолжал получать ошибку. Я не знал, что смогу сделать это и таким образом. Это дало мне общий формат, который я искал, хотя он все еще нуждается в некоторых манипуляциях. Спасибо!