pandas 中平均值的复杂计算
a complex computing of the average value in pandas
这是我在这个论坛上的第一个问题。
我正在进行实验,测量应用不同实验条件的设备的电流-电压曲线。
不同的实验条件编码成一个参数K
我正在使用 前后 电压扫描对电流 I
进行测量,V
从 O 到 2V,然后从 2V 到 -2V然后回到 0V。
对 K
的每个值进行多次测量,以获得每个电压点(反向和正向值)的电流平均值。每个测量值都归因于一个名为 iter
的参数(例如从 0 到 3)。
我已将所有数据收集到 pandas 数据帧 df
中,我将代码放在下面,该代码能够生成典型的 df
我拥有的(真实的太大了):
import numpy as np
import pandas as pd
K_col=[]
iter_col=[]
V_col=[]
I_col=[]
niter = 3
V_val = [0,1,2,1,0,-1,-2,-1,0]
K_val = [1,2]
for K in K_val:
for it in range(niter):
for V in V_val:
K_col.append(K)
iter_col.append(it+1)
V_col.append(V)
I_col.append((2*K+np.random.random())*V)
d={'K':K_col,'iter':iter_col,'V':V_col,'I':I_col}
df=pd.DataFrame(d)
我想计算每个电压下 I
的平均值,并比较实验条件 K
的影响。
例如,让我们看一下针对 K=1 进行的 2 次测量:
df[(df.K==1)&(df.iter.isin([1,2]))]
输出:
K iter V I
0 1 1 0 0.000000
1 1 1 1 2.513330
2 1 1 2 4.778719
3 1 1 1 2.430393
4 1 1 0 0.000000
5 1 1 -1 -2.705487
6 1 1 -2 -4.235055
7 1 1 -1 -2.278295
8 1 1 0 0.000000
9 1 2 0 0.000000
10 1 2 1 2.535058
11 1 2 2 4.529292
12 1 2 1 2.426209
13 1 2 0 0.000000
14 1 2 -1 -2.878359
15 1 2 -2 -4.061515
16 1 2 -1 -2.294630
17 1 2 0 0.000000
我们可以看到,对于实验 1 (iter=1),V 在 0 处多次出现(索引 0、4 和 8)。我不想丢失这些不同的数据点。
I_avg
的第一个数据点应该是 (I[0]+I[9])/2
,这对应于 0V 的第一个测量值。第二个数据点应该是 (I[1]+I[10])/2
,它对应于在 1V 下测量的 avg_I 随着 V 值的增加等......直到 (I[8]+I[17])/2
这将是我在 0V 的最后一个数据点。
我的第一个想法是使用 groupby()
方法,使用 K
和 V
作为键,但这行不通,因为 V
因此来回变化对于每个测量值,我们都有 V
的重复值,而 groupby 只会关注 V
.
的唯一值
我想要的最终数据框应该如下所示:
K V avg_I
0 1 0 0.000000
1 1 1 2.513330
2 1 2 4.778719
3 1 1 2.430393
4 1 0 0.000000
5 1 -1 -2.705487
6 1 -2 -4.235055
7 1 1 -2.278295
8 1 0 0.000000
9 1 0 0.000000
10 2 1 2.513330
11 2 2 4.778719
12 2 1 2.430393
13 2 0 0.000000
14 2 -1 -2.705487
15 2 -2 -4.235055
16 2 1 -2.278295
17 2 0 0.000000
有人知道怎么做吗?
如果我没有理解错的话,你想要一个新的数据点来表示每个 V 类别的平均 I。我们可以通过获取每个 V 的 I 的平均值然后将其映射到完整数据帧来实现这一点。
avg_I = df.groupby(['V'], as_index=False).mean()[['V', 'I']]
df['avg_I'] = df.apply(lambda x: float(avg_I['I'][avg_I['V'] == x['V']]), axis=1)
df.head()
输出:
K iter V I avg_I
0 1 1 0 0.00 0.00
1 1 1 1 2.34 3.55
2 1 1 2 4.54 6.89
3 1 1 1 2.02 3.55
4 1 1 0 0.00 0.00
df.plot()
为了计算均值并同时考虑迭代期间每个观察值的位置,您可以添加一个包含此信息的额外列,如下所示:
len_iter = 9
num_iter = len(df['iter'].unique())
num_K = len(df['K'].unique())
df['index'] = np.tile(np.arange(len_iter), num_iter*num_K)
然后计算分组依据和均值以获得所需的结果:
df.groupby(['K', 'V', 'index'])['I'].mean().reset_index().drop(['index'], axis=1)
K V I
0 1 -2 -5.070126
1 1 -1 -2.598104
2 1 -1 -2.576927
3 1 0 0.000000
4 1 0 0.000000
5 1 0 0.000000
6 1 1 2.232128
7 1 1 2.359398
8 1 2 4.824657
9 2 -2 -9.031487
10 2 -1 -4.125880
11 2 -1 -4.350776
12 2 0 0.000000
13 2 0 0.000000
14 2 0 0.000000
15 2 1 4.535478
16 2 1 4.492122
17 2 2 8.569701
这是我在这个论坛上的第一个问题。
我正在进行实验,测量应用不同实验条件的设备的电流-电压曲线。
不同的实验条件编码成一个参数K
我正在使用 前后 电压扫描对电流 I
进行测量,V
从 O 到 2V,然后从 2V 到 -2V然后回到 0V。
对 K
的每个值进行多次测量,以获得每个电压点(反向和正向值)的电流平均值。每个测量值都归因于一个名为 iter
的参数(例如从 0 到 3)。
我已将所有数据收集到 pandas 数据帧 df
中,我将代码放在下面,该代码能够生成典型的 df
我拥有的(真实的太大了):
import numpy as np
import pandas as pd
K_col=[]
iter_col=[]
V_col=[]
I_col=[]
niter = 3
V_val = [0,1,2,1,0,-1,-2,-1,0]
K_val = [1,2]
for K in K_val:
for it in range(niter):
for V in V_val:
K_col.append(K)
iter_col.append(it+1)
V_col.append(V)
I_col.append((2*K+np.random.random())*V)
d={'K':K_col,'iter':iter_col,'V':V_col,'I':I_col}
df=pd.DataFrame(d)
我想计算每个电压下 I
的平均值,并比较实验条件 K
的影响。
例如,让我们看一下针对 K=1 进行的 2 次测量:
df[(df.K==1)&(df.iter.isin([1,2]))]
输出:
K iter V I
0 1 1 0 0.000000
1 1 1 1 2.513330
2 1 1 2 4.778719
3 1 1 1 2.430393
4 1 1 0 0.000000
5 1 1 -1 -2.705487
6 1 1 -2 -4.235055
7 1 1 -1 -2.278295
8 1 1 0 0.000000
9 1 2 0 0.000000
10 1 2 1 2.535058
11 1 2 2 4.529292
12 1 2 1 2.426209
13 1 2 0 0.000000
14 1 2 -1 -2.878359
15 1 2 -2 -4.061515
16 1 2 -1 -2.294630
17 1 2 0 0.000000
我们可以看到,对于实验 1 (iter=1),V 在 0 处多次出现(索引 0、4 和 8)。我不想丢失这些不同的数据点。
I_avg
的第一个数据点应该是 (I[0]+I[9])/2
,这对应于 0V 的第一个测量值。第二个数据点应该是 (I[1]+I[10])/2
,它对应于在 1V 下测量的 avg_I 随着 V 值的增加等......直到 (I[8]+I[17])/2
这将是我在 0V 的最后一个数据点。
我的第一个想法是使用 groupby()
方法,使用 K
和 V
作为键,但这行不通,因为 V
因此来回变化对于每个测量值,我们都有 V
的重复值,而 groupby 只会关注 V
.
我想要的最终数据框应该如下所示:
K V avg_I
0 1 0 0.000000
1 1 1 2.513330
2 1 2 4.778719
3 1 1 2.430393
4 1 0 0.000000
5 1 -1 -2.705487
6 1 -2 -4.235055
7 1 1 -2.278295
8 1 0 0.000000
9 1 0 0.000000
10 2 1 2.513330
11 2 2 4.778719
12 2 1 2.430393
13 2 0 0.000000
14 2 -1 -2.705487
15 2 -2 -4.235055
16 2 1 -2.278295
17 2 0 0.000000
有人知道怎么做吗?
如果我没有理解错的话,你想要一个新的数据点来表示每个 V 类别的平均 I。我们可以通过获取每个 V 的 I 的平均值然后将其映射到完整数据帧来实现这一点。
avg_I = df.groupby(['V'], as_index=False).mean()[['V', 'I']]
df['avg_I'] = df.apply(lambda x: float(avg_I['I'][avg_I['V'] == x['V']]), axis=1)
df.head()
输出:
K iter V I avg_I
0 1 1 0 0.00 0.00
1 1 1 1 2.34 3.55
2 1 1 2 4.54 6.89
3 1 1 1 2.02 3.55
4 1 1 0 0.00 0.00
df.plot()
为了计算均值并同时考虑迭代期间每个观察值的位置,您可以添加一个包含此信息的额外列,如下所示:
len_iter = 9
num_iter = len(df['iter'].unique())
num_K = len(df['K'].unique())
df['index'] = np.tile(np.arange(len_iter), num_iter*num_K)
然后计算分组依据和均值以获得所需的结果:
df.groupby(['K', 'V', 'index'])['I'].mean().reset_index().drop(['index'], axis=1)
K V I
0 1 -2 -5.070126
1 1 -1 -2.598104
2 1 -1 -2.576927
3 1 0 0.000000
4 1 0 0.000000
5 1 0 0.000000
6 1 1 2.232128
7 1 1 2.359398
8 1 2 4.824657
9 2 -2 -9.031487
10 2 -1 -4.125880
11 2 -1 -4.350776
12 2 0 0.000000
13 2 0 0.000000
14 2 0 0.000000
15 2 1 4.535478
16 2 1 4.492122
17 2 2 8.569701