Python Pandas - вычисление статистики по TimeSeriesIndexedData для каждого клиента - PullRequest
0 голосов
/ 08 февраля 2019
    UsageDate               CustID1  CustID2   .... CustIDn
0   2018-01-01 00:00:00     1.095
1   2018-01-01 01:00:00     1.129
2   2018-01-01 02:00:00     1.165
3   2018-01-01 04:00:00     1.697
. 
.
m   2018-31-01 23:00:00     1.835                     (m,n)

Фрейм данных (df) имеет m строк и n столбцов.m - почасовой индекс TimeSeries, который начинается с первого часа месяца до последнего часа месяца.Колонны - это клиенты, которых почти 100 000.Значения в каждой ячейке Dataframe являются значениями энергопотребления.

Для каждого клиента мне нужно рассчитать: 1) Среднее значение каждого часа использования, то есть среднее значение 1-го часа каждого дня в месяце, 2-го часа каждого дня в месяце и т. Д.

2) Сумма использования каждого клиента

3) 3 часа работы - для клиента x это может быть "2018-01-01 01:00:00", "2018-11-0105:00:00 "" 2018-21-01 17:00:00 "

4) Нижние 3 часа использования - объяснение, аналогичное приведенному выше

5) Среднее использование для каждого клиента вмесяц

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

Для суммирования использования для каждого клиента я попытался: df_temp = pd.DataFrame(columns=["TotalUsage"])

for col in df.columns:

`df_temp[col,"TotalUsage"] = df[col].apply.sum()`

Однако эта и многие версии, которые я попробовал,не помогает мне решить проблему.

Пожалуйста, помогите мне с подходом и как думать о таких проблемах.

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

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Я не уверен, что это вся информация, которую вы ищете, но она укажет вам правильное направление:

import pandas as pd
import numpy as np

# sample data for 3 days
np.random.seed(1)
data = pd.DataFrame(pd.date_range('2018-01-01', periods= 72, freq='H'), columns=['UsageDate'])
data2  = pd.DataFrame(np.random.rand(72,5), columns=[f'ID_{i}' for i in range(5)])
df = data.join([data2])
# print('Sample Data:')
# print(df.head())
# print()

# mean of every month and hour per year
# groupby year month hour then find the mean of every hour in a given year and month
mean_data = df.groupby([df['UsageDate'].dt.year, df['UsageDate'].dt.month, df['UsageDate'].dt.hour]).mean()
mean_data.index.names = ['UsageDate_year', 'UsageDate_month', 'UsageDate_hour']
# print('Mean Data:')
# print(mean_data.head())
# print()

# use set_index with max and head
top_3_Usage_hours = df.set_index('UsageDate').max(1).sort_values(ascending=False).head(3)
# print('Top 3:')
# print(top_3_Usage_hours)
# print()

# use set_index with min and tail
bottom_3_Usage_hours = df.set_index('UsageDate').min(1).sort_values(ascending=False).tail(3)
# print('Bottom 3:')
# print(bottom_3_Usage_hours)

out:

Sample Data:
            UsageDate      ID_0      ID_1      ID_2      ID_3      ID_4
0 2018-01-01 00:00:00  0.417022  0.720324  0.000114  0.302333  0.146756
1 2018-01-01 01:00:00  0.092339  0.186260  0.345561  0.396767  0.538817
2 2018-01-01 02:00:00  0.419195  0.685220  0.204452  0.878117  0.027388
3 2018-01-01 03:00:00  0.670468  0.417305  0.558690  0.140387  0.198101
4 2018-01-01 04:00:00  0.800745  0.968262  0.313424  0.692323  0.876389

Mean Data:
                                                   ID_0      ID_1      ID_2  \
UsageDate_year UsageDate_month UsageDate_hour                                 
2018           1               0               0.250716  0.546475  0.202093   
                               1               0.414400  0.264330  0.535928   
                               2               0.335119  0.877191  0.380688   
                               3               0.577429  0.599707  0.524876   
                               4               0.702336  0.654344  0.376141   

                                                   ID_3      ID_4  
UsageDate_year UsageDate_month UsageDate_hour                      
2018           1               0               0.244185  0.598238  
                               1               0.400003  0.578867  
                               2               0.623516  0.477579  
                               3               0.429835  0.510685  
                               4               0.503908  0.595140  

Top 3:
UsageDate
2018-01-01 21:00:00    0.997323
2018-01-03 23:00:00    0.990472
2018-01-01 08:00:00    0.988861
dtype: float64

Bottom 3:
UsageDate
2018-01-01 19:00:00    0.002870
2018-01-03 02:00:00    0.000402
2018-01-01 00:00:00    0.000114
dtype: float64

Для топ идно 3, если вы хотите найти минимальную сумму по строкам, то:

df.set_index('UsageDate').sum(1).sort_values(ascending=False).tail(3)
0 голосов
/ 08 февраля 2019

Это похоже на работу для pandas.groupby .

(Я не тестировал код, потому что у меня не было хорошего образца набора данных для работы. Если естьошибки, дайте мне знать.)

Для некоторых ваших требований вам нужно добавить столбец с часами:

 df['hour']=df['UsageDate'].dt.hour

1) Среднее значение по часам.

 mean_by_hour=df.groupby('hour').mean()

2) Суммирование по пользователю.

 sum_by_uers=df.sum()

3) Максимальное использование клиентом.Нижние 3 часа использования - объяснение, аналогичное приведенному выше .-- Я не совсем понимаю ваш желаемый результат, вы можете задавать слишком много разных вопросов в этом вопросе.Если вам нужен час, а не значение, я думаю, вам, возможно, придется перебирать столбцы.Добавление примера может помочь.

4) Тот же комментарий.

5) Среднее значение по клиенту.

mean_by_cust = df.mean()
...