gpt4 book ai didi

python - 将聚合函数应用于 Pandas 分层索引中的多个索引片的系统方法

转载 作者:行者123 更新时间:2023-12-01 00:59:59 24 4
gpt4 key购买 nike

问题

我希望有一种更系统的方法来聚合多个频率间隔的频率。

以下数据帧包含表示时频数据的随机数据。其列索引包含以下级别:

  1. 条件
  2. channel
  3. 频率

生成数据帧的代码如下:

import numpy as np
import pandas as pd
pidx = pd.IndexSlice

D=np.zeros((32,2,2,6))# timepoints, conditions, channels, frequencies
for i in range(6):
D[:,0,0,i]=np.arange(i,i+32,1) # C0, ch01
D[:,0,1,i]=np.arange(i+1,i+32+1,1) # C0, ch02
D[:,1,0,i]=np.arange(i+2,i+32+2,1) # C1, ch01
D[:,1,1,i]=np.arange(i+3,i+32+3,1) # C1, ch02

conditions = ['C0', 'C1']
channels = ["ch{:02}".format(i) for i in np.arange(1,3)]
frequencies = np.arange(1, 7)

# columnns multi index
cidx = pd.MultiIndex.from_product([conditions,channels,frequencies])
# reshape to 2D
D = D.reshape((D.shape[0], -1))
# create DataFrame
df = pd.DataFrame(D, columns=cidx)

当前解决方案

目前我执行以下操作

fbands = {
'fb1' : [pidx[1:3]],
'fb2' : [pidx[2:5]],
'fb3' : [pidx[4:6]]
}
def frequencyband_mean(df, fb):
return df.loc(axis=1)[:,:,fb].groupby(axis=1,level=[0,1]).mean()

dffbands = dict((k, frequencyband_mean(df, fbands[k])) for k in fbands)
df_result = pd.concat(dffbands, axis=1)

但是,后面的代码不会维护列索引级别,更具体地说,df_result 的第一级包含 fbands 中定义的每个频率间隔的名称。我会通过交换列级别来解决这个问题,但这似乎很麻烦。

问题

我想知道是否有一种更系统的方法可以一次性将聚合函数应用于多个频率间隔,同时保持列索引级别。最终列索引的最后一层应该看起来像

  1. 条件
  2. channel
  3. 频率间隔名称(例如 fb1fb2fb3)

最佳答案

如果我猜对了,那么我会这样做:

fbands={
'fb1' : [0,3],
'fb2' : [2,5],
'fb3' : [4,6]
}

for co_i in df.columns.levels[0]:
for cha_i in df.columns.levels[1]:
for k,v in fbands.items():
df[co_i,cha_i,k] = df[co_i,cha_i,].T[v[0]:v[1]].mean()

更新:请注意,此处的切片并非基于标签,因此您实际上需要 v[0]-1:v[1];为了使这一点更清楚,我建议您简化您的 df:

D=np.zeros((32,2,2,6))
for i in range(6):
D[:,0,0,i]=np.arange(i,i+32,1) # C0, ch01
D[:,0,1,i]=np.arange(i+1,i+32+1,1) # C0, ch02
D[:,1,0,i]=np.arange(i+2,i+32+2,1) # C1, ch01
D[:,1,1,i]=np.arange(i+3,i+32+3,1) # C1, ch02

使得df.head(3)返回:

    C0                                                          C1                                                        
ch01 ch02 ch01 ch02
1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
0 0.0 1.0 2.0 3.0 4.0 5.0 1.0 2.0 3.0 4.0 5.0 6.0 2.0 3.0 4.0 5.0 6.0 7.0 3.0 4.0 5.0 6.0 7.0 8.0
1 1.0 2.0 3.0 4.0 5.0 6.0 2.0 3.0 4.0 5.0 6.0 7.0 3.0 4.0 5.0 6.0 7.0 8.0 4.0 5.0 6.0 7.0 8.0 9.0
2 2.0 3.0 4.0 5.0 6.0 7.0 3.0 4.0 5.0 6.0 7.0 8.0 4.0 5.0 6.0 7.0 8.0 9.0 5.0 6.0 7.0 8.0 9.0 10.0

这样,我们实际上可以验证我们的期望!我现在使用 fbands 作为数组,而不是字典,这样排序就变得很好(也可以使用 collections 中的 OrderedDict )。

fbands=[
['fb1',[1,3]],
['fb2',[2,5]],
['fb3',[4,6]]
]
for co_i in df.columns.levels[0]:
for cha_i in df.columns.levels[1]:
for fi in range(len(fbands)):
k=fbands[fi][0]
v=fbands[fi][1]
df[co_i,cha_i,k] = df[co_i,cha_i,].T[v[0]-1:v[1]].mean()

for i in range(7):
df=df.drop(i, axis=1, level=2)

print(df.head(3))

返回:

    C0                            C1                         
ch01 ch02 ch01 ch02
fb1 fb2 fb3 fb1 fb2 fb3 fb1 fb2 fb3 fb1 fb2 fb3
0 1.0 2.5 4.0 2.0 3.5 5.0 3.0 4.5 6.0 4.0 5.5 7.0
1 2.0 3.5 5.0 3.0 4.5 6.0 4.0 5.5 7.0 5.0 6.5 8.0
2 3.0 4.5 6.0 4.0 5.5 7.0 5.0 6.5 8.0 6.0 7.5 9.0

现在,fb* 列实际上反射(reflect)了频率 fb1:[1,2,3]、fb2:[2,3,4,5] 和 fb3:[4,5 的平均值,6],正如我希望你想要的

更新 2:请注意,如果您像这样设置频率:

frequencies = ["f{0}".format(i) for i in np.arange(1,7)]

那么你可以例如在 C0 内的 ch01 中创建频率平均值 'f1','f2','f3',如下所示:

df['C0','ch01','fb1'] = df.loc(axis=1)[pd.IndexSlice['C0','ch01',['f1','f2','f3'],:]].mean(axis=1)

关于python - 将聚合函数应用于 Pandas 分层索引中的多个索引片的系统方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55885348/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com