Генерация ежемесячных средних для всех столбцов без инициализации списка для каждого столбца? - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть данные временных рядов, которые я хочу получить среднее значение для каждого месяца, для каждого столбца. Я успешно сделал это, но путем создания списка для каждого столбца - что было бы невозможно для тысяч столбцов.

Как мне адаптировать мой код для автоматического заполнения имен и значений столбцов в фрейм данных тысячами столбцов?

Для контекста, эти данные имеют 20 наблюдений в час в течение 12 месяцев.

Исходные данные:

timestamp    56TI1164   56FI1281    56TI1281    52FC1043    57TI1501

2016-12-31 23:55:00 117.9673    17876.27    39.10074    9302.815    49.23963
2017-01-01 00:00:00 118.1080    17497.48    39.10759    9322.773    48.97919
2017-01-01 00:05:00 117.7809    17967.33    39.11348    9348.223    48.94284

Выход:

    56TI1164    56FI1281    56TI1281    52FC1043    57TI1501
0   106.734147  16518.428734    16518.428734    7630.187992 45.992215
1   115.099825  18222.911023    18222.911023    9954.252911 47.334477
2   111.555504  19090.607211    19090.607211    9283.845649 48.939581
3   102.408996  18399.719852    18399.719852    7778.897037 48.130057
4   118.371951  20245.378742    20245.378742    9024.424210 64.796939
5   127.580516  21859.212675    21859.212675    9595.477455 70.952311
6   134.159082  22349.853561    22349.853561    10305.252112    75.195480
7   137.990638  21122.233427    21122.233427    10024.709142    74.755469
8   144.958318  18633.290818    18633.290818    11193.381098    66.776627
9   122.406489  20258.135923    20258.135923    10504.604420    61.793355
10  104.817850  18762.070668    18762.070668    9361.052983 51.802615
11  106.589672  20049.809554    20049.809554    9158.685383 51.611633

Успешный код:

#separate data into months
v = list(range(1,13))
data_month = []

for i in v:
    data_month.append(data[(data.index.month==i)])


# average per month for each sensor

mean_56TI1164 = []
mean_56FI1281 = []
mean_56TI1281 = []
mean_52FC1043 = []
mean_57TI1501 = []

for i in range(0,12):


    mean_56TI1164.append(data_month[i]['56TI1164'].mean())
    mean_56FI1281.append(data_month[i]['56FI1281'].mean())
    mean_56TI1281.append(data_month[i]['56FI1281'].mean())
    mean_52FC1043.append(data_month[i]['52FC1043'].mean())
    mean_57TI1501.append(data_month[i]['57TI1501'].mean())


   mean_df = {'56TI1164': mean_56TI1164, '56FI1281': mean_56FI1281, '56TI1281': mean_56TI1281, '52FC1043': mean_52FC1043, '57TI1501': mean_57TI1501}

mean_df = pd.DataFrame(mean_df, columns= ['56TI1164', '56FI1281', '56TI1281', '52FC1043', '57TI1501']) 

mean_df

Неудачная попытка уплотнения:

col = list(data.columns)
mean_df = pd.DataFrame()

for i in range(0,12):

    for j in col:

        mean_df[j].append(data_month[i][j].mean())

mean_df

1 Ответ

0 голосов
/ 17 апреля 2019

По предложению Дж. Андерсона вы можете использовать groupby, как в этом примере:

import pandas as pd
import io

csv="""timestamp    56TI1164   56FI1281    56TI1281    52FC1043    57TI1501
2016-12-31 23:55:00 117.9673    17876.27    39.10074    9302.815    49.23963
2017-01-01 00:00:00 118.1080    17497.48    39.10759    9322.773    48.97919
2017-01-01 00:05:00 117.7809    17967.33    39.11348    9348.223    48.94284
2018-01-01 00:05:00 120.0000    17967.33    39.11348    9348.223    48.94284
2018-01-01 00:05:00 124.0000    17967.33    39.11348    9348.223    48.94284"""

# The following lines read your data into a pandas dataframe;
# it may help if your data comes in the form you wrote in the question

dateparse = lambda x: pd.datetime.strptime(x, '%Y-%m-%d %H:%M:%S')
data = pd.read_csv(io.StringIO(csv), sep='\s+(?!\d\d:\d\d:\d\d)', \
                   date_parser=dateparse, index_col=0, engine='python')


# Here is where your data is resampled by month and mean is calculated

data.groupby(pd.Grouper(freq='M')).mean()

# If you have missing months, use this instead:
#data.groupby(pd.Grouper(freq='M')).mean().dropna()

Результат data.groupby(pd.Grouper(freq='M')).mean().dropna() будет:

            56TI1164    56FI1281    56TI1281    52FC1043    57TI1501
timestamp                   
2016-12-31  117.96730   17876.270   39.100740   9302.815    49.239630
2017-01-31  117.94445   17732.405   39.110535   9335.498    48.961015
2018-01-31  122.00000   17967.330   39.113480   9348.223    48.942840

Обратите внимание, что я использовал data.groupby(pd.Grouper(freq='M')).mean().dropna(), чтобы избавиться от NaN за пропущенные месяцы (я добавил некоторые данные за январь 2018 года, пропустив, что между ними). ​​

Также обратите внимание, что извилистый read_csv использует регулярное выражение в качестве разделителя: \s+ означает один или несколько пробельных символов, в то время как (?!\d\d:\d\d:\d\d) означает «пропустить этот пробел, если за ним следует что-то вроде 23:55:00». Последний engine='python' избегает предупреждений, когда read_csv() используется с регулярным выражением

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...