python - 将特定于组的功能添加到 pandas 数据框

标签 python pandas pandas-groupby

我有一个时间序列数据框,其中包含数千个加油站的汽油价格 (uuid),多年来每天更新多次。

(可通过:git clone https://dev.azure.com/tankerkoenig/tankerkoenig-data/_git/tankerkoenig-data )

df = 
datetime,uuid,diesel,e5,e10
2018-01-31 00:01:06+01,c03c846e-64ec-437f-9a52-9eda8088c4b2,1.239,1.419,1.399
2018-01-31 00:03:06+01,6dc575da-3c85-430c-a17a-6efdae0dcf5a,1.249,1.419,1.399

我想添加一个功能列,告诉每个柴油的每日 min()max() 值,每个 uuid(加油站)的 e5,e10 价格。

因此我添加一个日期列:

df['date'] = index.date

然后对数据框进行分组:

df.groupby(['uuid','date','datetime']).sum()

                                                                            diesel  e5      e10
                                uuid    date        datetime            
00006210-0037-4444-8888-acdc00006210    2018-01-01  2018-01-01 06:33:06     1.189   1.389   1.369
                                                    2018-01-01 06:39:05     1.189   1.349   1.329

我现在如何添加特定于组的列。 我想使用 GroupBy.apply() 可能是一种方法,但这非常慢或不起作用。

def fun(df):
    df['diesel_low'] = df['diesel'].min()
    return df
df.groupby(['uuid','date','datetime']).apply(lambda x: fun(x))

最佳答案

我相信您需要通过 GroupBy.agg 进行聚合,然后展平列中的 MultiIndex 并按 DataFrame.reset_index 将索引转换为列:

print (df)
                                                           uuid  diesel  e5  \
datetime                                                                      
2018-01-31 00:01:06+01:00  c03c846e-64ec-437f-9a52-9eda8088c4b2      15   1   
2018-01-31 00:03:06+01:00  6dc575da-3c85-430c-a17a-6efdae0dcf5a       9   4   
2018-01-31 00:01:06+01:00  c03c846e-64ec-437f-9a52-9eda8088c4b2      19   1   
2018-01-31 00:03:06+01:00  6dc575da-3c85-430c-a17a-6efdae0dcf5a      12   9   

                           e10  
datetime                        
2018-01-31 00:01:06+01:00    4  
2018-01-31 00:03:06+01:00    1  
2018-01-31 00:01:06+01:00    5  
2018-01-31 00:03:06+01:00   12  

df['date'] = df.index.date
cols = ['diesel','e5','e10']
df1 = df.groupby(['uuid','date'])[cols].agg([('low', 'min'),('high', 'max')])
df1.columns = df1.columns.map('_'.join)
print (df1)
                                                 diesel_low  diesel_high  \
uuid                                 date                                  
6dc575da-3c85-430c-a17a-6efdae0dcf5a 2018-01-31           9           12   
c03c846e-64ec-437f-9a52-9eda8088c4b2 2018-01-31          15           19   

                                                 e5_low  e5_high  e10_low  \
uuid                                 date                                   
6dc575da-3c85-430c-a17a-6efdae0dcf5a 2018-01-31       4        9        1   
c03c846e-64ec-437f-9a52-9eda8088c4b2 2018-01-31       1        1        4   

                                                 e10_high  
uuid                                 date                  
6dc575da-3c85-430c-a17a-6efdae0dcf5a 2018-01-31        12  
c03c846e-64ec-437f-9a52-9eda8088c4b2 2018-01-31         5  

df = df.join(df1, on=['uuid','date'])
print (df)
                                                           uuid  diesel  e5  \
datetime                                                                      
2018-01-31 00:01:06+01:00  c03c846e-64ec-437f-9a52-9eda8088c4b2      15   1   
2018-01-31 00:03:06+01:00  6dc575da-3c85-430c-a17a-6efdae0dcf5a       9   4   
2018-01-31 00:01:06+01:00  c03c846e-64ec-437f-9a52-9eda8088c4b2      19   1   
2018-01-31 00:03:06+01:00  6dc575da-3c85-430c-a17a-6efdae0dcf5a      12   9   

                           e10        date  diesel_low  diesel_high  e5_low  \
datetime                                                                      
2018-01-31 00:01:06+01:00    4  2018-01-31          15           19       1   
2018-01-31 00:03:06+01:00    1  2018-01-31           9           12       4   
2018-01-31 00:01:06+01:00    5  2018-01-31          15           19       1   
2018-01-31 00:03:06+01:00   12  2018-01-31           9           12       4   

                           e5_high  e10_low  e10_high  
datetime                                               
2018-01-31 00:01:06+01:00        1        4         5  
2018-01-31 00:03:06+01:00        9        1        12  
2018-01-31 00:01:06+01:00        1        4         5  
2018-01-31 00:03:06+01:00        9        1        12  

另一个解决方案:

df['date'] = df.index.date
cols = ['diesel','e5','e10']
df1 = df.groupby(['uuid','date'])[cols].transform('max').add_suffix('_high')
df2 = df.groupby(['uuid','date'])[cols].transform('min').add_suffix('_low')

df = pd.concat([df, df1, df2], axis=1)
print (df)
                                                           uuid  diesel  e5  \
datetime                                                                      
2018-01-31 00:01:06+01:00  c03c846e-64ec-437f-9a52-9eda8088c4b2      15   1   
2018-01-31 00:03:06+01:00  6dc575da-3c85-430c-a17a-6efdae0dcf5a       9   4   
2018-01-31 00:01:06+01:00  c03c846e-64ec-437f-9a52-9eda8088c4b2      19   1   
2018-01-31 00:03:06+01:00  6dc575da-3c85-430c-a17a-6efdae0dcf5a      12   9   

                           e10        date  diesel_high  e5_high  e10_high  \
datetime                                                                     
2018-01-31 00:01:06+01:00    4  2018-01-31           19        1         5   
2018-01-31 00:03:06+01:00    1  2018-01-31           12        9        12   
2018-01-31 00:01:06+01:00    5  2018-01-31           19        1         5   
2018-01-31 00:03:06+01:00   12  2018-01-31           12        9        12   

                           diesel_low  e5_low  e10_low  
datetime                                                
2018-01-31 00:01:06+01:00          15       1        4  
2018-01-31 00:03:06+01:00           9       4        1  
2018-01-31 00:01:06+01:00          15       1        4  
2018-01-31 00:03:06+01:00           9       4        1  

关于python - 将特定于组的功能添加到 pandas 数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56042202/

相关文章:

Windows Server 上的 Python - 获取用户访问共享文件

python - 根据发生情况合并行,同时维护 Python 中 DataFrame 中的唯一值

python - Pandas 数据框中多列的聚合

python - 用 Pandas 计算指数移动平均线

python - pandas:计算 Blackman 窗口的最大值:缺少函数 pandas.core.window.Window.[max,apply]

python - 获取 pandas python 中每个类别/组的重复值计数

python - Imread 返回 4 个维度,而预期返回 3 个维度。为什么?

python - 如何引发包含 Unicode 字符串的异常?

python - 创建一个可变长度的颜色查找表

python - 通过装饰器断言 Pandas 数据框具有日期时间索引