Как эффективно реорганизовать фрейм данных в записи даты и времени, используя Pandas в Python? - PullRequest
0 голосов
/ 10 апреля 2020

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

enter image description here

Я хочу, чтобы это выглядело так (индекс даты, столбцы станций):

enter image description here

Имена станций не важны, мне пришлось использовать другой файл, чтобы показать рабочий пример.

Этот первый кадр данных имеет столбцы 0 -23, которые представляют часы дня. Он также содержит информацию о дате и станции (местонахождение) в каждой строке. Мне нужно, чтобы индекс (или строка) был временем даты, объединяющим час из столбцов и дату из строк. Мне нужно, чтобы каждая станция была столбцом, а не сохраненным в строке.

Я использовал следующий код для его достижения, но обработка даже небольшого числа строк занимает очень много времени.

import os
import pandas as pd
idx = pd.IndexSlice

df=pd.read_csv(os.path.join(filepath,newfilename)) # get data
df=df[df['POC']==1] #only keep primary intrument at each site
cols=['Site AQS', 'Date (LST)', '0', '1', '2', '3', '4', '5', '6',
       '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18',
       '19', '20', '21', '22', '23']

df=df[cols] #subset to only relevant columns

df_align1=pd.pivot_table(df,index='Date (LST)',columns=['Site AQS'])  #pivot data to easier view

ozone_df=pd.DataFrame() #create ouput df

for date in df_align1.index:
    for station in df_align1.columns.get_level_values(1):
        for i in df_align1.columns.get_level_values(0):
            ozone_df.loc[pd.to_datetime(date+' '+str(i)+':00'),station]=df_align1.loc[date,idx[i, station]]

Вот ссылка на мои примеры данных, так что вы можете проверить код, который я написал.

https://drive.google.com/file/d/11Lzl_m_EBCxoBEutl0UP6_TKq6TNgVZI/view?usp=sharing

PS: Извините за плохие изображения, я использую удаленный компьютер и не могу получить хороший снимок экрана.

1 Ответ

2 голосов
/ 11 апреля 2020

Вы можете использовать melt и pivot_table

# setup the initial dataframe
dates = np.repeat(pd.date_range(start='1/1/2018', end='1/03/2018'), 3)
stations = np.tile(['O', 'E', 'L',], 3)
vals = np.random.rand(len(dates),len(cols))
df = pd.DataFrame(vals)
df.insert(0, 'Date', dates)
df.insert(1, 'Station', stations)

Расплавить фрейм данных

melted = df.melt(id_vars=['Date', 'Station'], value_vars=df.columns[2:])

Теперь данные выглядят так

    Date    Station variable    value
0   2018-01-01  O   0   0.340432
1   2018-01-01  E   0   0.865012
2   2018-01-01  L   0   0.994935
3   2018-01-02  O   0   0.274560
4   2018-01-02  E   0   0.096046

Далее вам нужно создать новый столбец даты из даты и переменной (прежние столбцы 0-23)

melted['Date2'] = melted['Date'] + pd.to_timedelta(melted['variable'].astype(int), unit='hours')

Наконец, создайте сводную таблицу со станциями в качестве столбцов

melted.pivot_table(index='Date2', columns='Station', values='value')

Теперь данные выглядят так:

Station                E           L           O
Date2           
2018-01-01 00:00:00 0.865012    0.994935    0.340432
2018-01-01 01:00:00 0.167927    0.605892    0.271139
2018-01-01 02:00:00 0.314101    0.473481    0.036693
2018-01-01 03:00:00 0.060521    0.462390    0.073077
2018-01-01 04:00:00 0.799032    0.420461    0.52114
...