在多索引熊猫数据框中使用 groupby 时计算时间和空间梯度

Posted

技术标签:

【中文标题】在多索引熊猫数据框中使用 groupby 时计算时间和空间梯度【英文标题】:Calculating temporal and sptial gradients while using groupby in multi-index pandas dataframe 【发布时间】:2021-10-22 05:44:06 【问题描述】:

假设我有以下样本 pandas 数据框,其中包含沿一列土壤指定深度处的含水量(即“wc”)值:

import pandas as pd

df = pd.DataFrame([[1, 2,5,3,1], [1, 3, 5,3, 2], [4, 6, 6,3,1], [1, 2,5,3,1], [1, 3, 5,3, 2], [4, 6, 6,3,1]], columns=pd.MultiIndex.from_product([['wc'], [10, 20, 30, 45, 80]]))

df['model'] = [5,5, 5, 6,6,6]

df['time'] = [0, 1, 2,0, 1, 2]

df.set_index(['time', 'model'], inplace=True)

>> df
[Out]:
           wc            
           10 20 30 45 80
time model               
0    5      1  2  5  3  1
1    5      1  3  5  3  2
2    5      4  6  6  3  1
0    6      1  2  5  3  1
1    6      1  3  5  3  2
2    6      4  6  6  3  1

我想计算以下结构中每个模型“组”的空间(列之间)和时间(行之间)梯度:

           wc             temp_grad      spat_grad
           10 20 30 45 80 10 20 30 45 80 10 20 30 45 
time model               
0    5      1  2  5  3  1
1    5      1  3  5  3  2
2    5      4  6  6  3  1
0    6      1  2  5  3  1
1    6      1  3  5  3  2
2    6      4  6  6  3  1

我的尝试涉及首先为时间梯度编写一个函数并将其与 groupby 相结合:

def temp_grad(df):
    temp_grad = np.gradient(df[('wc', 10.0)], df.index.get_level_values(0))
    return pd.Series(temp_grad, index=x.index)

df[('temp_grad', 10.0)] = (df.groupby(level = ['model'], group_keys=False)
                              .apply(temp_grad))

但我不确定如何自动执行此操作以应用于所有 wc 列以及导航多索引问题。

【问题讨论】:

【参考方案1】:

假设您编写的函数实际上是您想要的,那么对于 temp_grad,您可以一次执行 apply 中的所有列。使用 np.gradient 与您在函数中使用的方式相同,但沿轴 = 0(行)指定。构建了一个以索引和列作为原始数据的数据框。对于spat_grad,我认为model 并不重要,所以不需要groupby,直接在df['wc'] 上执行np.gradient,这次沿着axis=1(列)。以相同的方式构建数据框。要获得预期的输出,concat 他们三个都喜欢:

df = pd.concat([
    df['wc'], # original data
    # add the temp_grad
    df['wc'].groupby(level = ['model'], group_keys=False)
      .apply(lambda x: #do all the columns at once, specifying the axis in gradient
             pd.DataFrame(np.gradient(x, x.index.get_level_values(0), axis=0), 
                          columns=x.columns, index=x.index)), # build a dataframe 
    # for spat, no need of groupby as it is row-wise operation
    # change the axis, and the values for the x
    pd.DataFrame(np.gradient(df['wc'], df['wc'].columns, axis=1),
                 columns=df['wc'].columns, index=df['wc'].index)
    ], 
    keys=['wc','temp_grad','spat_grad'],  # redefine the multiindex columns
    axis=1 # concat along the columns
)

你得到

print(df)
           wc             temp_grad                     spat_grad       \
           10 20 30 45 80        10   20   30   45   80        10   20   
time model                                                               
0    5      1  2  5  3  1       0.0  1.0  0.0  0.0  1.0       0.1  0.2   
1    5      1  3  5  3  2       1.5  2.0  0.5  0.0  0.0       0.2  0.2   
2    5      4  6  6  3  1       3.0  3.0  1.0  0.0 -1.0       0.2  0.1   
0    6      1  2  5  3  1       0.0  1.0  0.0  0.0  1.0       0.1  0.2   
1    6      1  3  5  3  2       1.5  2.0  0.5  0.0  0.0       0.2  0.2   
2    6      4  6  6  3  1       3.0  3.0  1.0  0.0 -1.0       0.2  0.1   

                                          
                  30        45        80  
time model                                
0    5      0.126667 -0.110476 -0.057143  
1    5      0.066667 -0.101905 -0.028571  
2    5     -0.080000 -0.157143 -0.057143  
0    6      0.126667 -0.110476 -0.057143  
1    6      0.066667 -0.101905 -0.028571  
2    6     -0.080000 -0.157143 -0.057143  

【讨论】:

以上是关于在多索引熊猫数据框中使用 groupby 时计算时间和空间梯度的主要内容,如果未能解决你的问题,请参考以下文章

如何更改熊猫数据框中多索引的外层索引?

访问熊猫数据框中内部多索引级别的最后一个元素

在 groupby 熊猫对象上应用 rolling() 时,多索引重复

在熊猫多索引数据框中返回满足逻辑索引条件的每个组的最后一行[重复]

忽略熊猫 groupby 组中的 NaN 的标准错误

如何对熊猫中的多索引进行分组?