在多索引pandas数据框架中使用groupby计算时空梯度



假设我有以下样本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列以及导航多索引问题。

假设您编写的函数实际上是您想要的,那么对于temp_grad,您可以一次完成应用程序中的所有列。使用np.gradient的方式与您在函数中所做的相同,但指定沿轴=0(行)。构建一个以索引和列作为原始数据的数据框架。对于spat_grad,我认为model并不重要,所以不需要groupby,直接在df['wc']上做np.gradient,这次沿着轴=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  

相关内容

  • 没有找到相关文章

最新更新