首页 > 解决方案 > Python Pandas - 为每个客户计算 TimeSeriesIndexedData 的统计数据

问题描述

    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 是每小时时间序列索引,从每月的第一个小时开始到每月的最后一个小时。列是几乎 100,000 的客户。Dataframe 的每个单元格的值是能耗值。

对于每个客户,我需要计算:1)每小时使用的平均值 - 所以基本上是一个月中每天的第一个小时,一个月中每天的第二个小时等的平均值。

2)每个客户的使用情况汇总

3)前 3 个使用时间 - 对于客户 x,可以是“2018-01-01 01:00:00”、“2018-11-01 05: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()`

但是,我尝试过的这个和许多版本都没有帮助我解决问题。

请帮助我提供一种方法以及如何考虑此类问题。

此外,由于数据帧很大,如果我们可以讨论计算复杂性以及如何减少计算时间,将会很有帮助。

标签: pythonpandasdataframeaggregation

解决方案


我不确定这是否是您正在寻找的所有信息,但它会为您指明正确的方向:

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)

出去:

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)

推荐阅读