当值相同时,透视表中不需要的平均值



当存在相同的值时,pivot_table取平均值(默认为aggfunc='mean')

例如:

d=pd.DataFrame(data={
'x_values':[13.4,13.08,12.73,12.,33.,23.,12.],
'y_values': [1.54, 1.47,1.,2.,4.,4.,3.],
'experiment':['e', 'e', 'e', 'f', 'f','f','f']})
print(pd.pivot_table(d, index='x_values', 
columns='experiment', values='y_values',sort=False))

的回报:

experiment     e    f
x_values             
13.40       1.54  NaN
13.08       1.47  NaN
12.73       1.00  NaN
12.00        NaN  2.5
33.00        NaN  4.0
23.00        NaN  4.0

可以看到f中出现了一个新值(2.5,即2的平均值)。和3)。

但是我想保持列表在pandas

中的样子
experiment     e    f
x_values             
13.40       1.54  NaN
13.08       1.47  NaN
12.73       1.00  NaN
12.00        NaN  2.0
33.00        NaN  4.0
23.00        NaN  4.0
12.00        NaN  3.0

我试着用aggfunc=list跟着explode玩,但在这种情况下,顺序丢失了…

感谢

这是我的解决方案。您真的不想在x_values透视(因为有副本)。因此,在x_valuesid_col上添加一个新的唯一列(id_col)和枢轴。然后你需要做一些清理工作:

(d
.assign(id_col=range(len(d)))
.pivot(index=['x_values', 'id_col'], columns='experiment')
.reset_index()
.drop(columns='id_col')
.set_index('x_values')
)

输出如下:

y_values     
experiment        e    f
x_values                
12.00           NaN  2.0
12.00           NaN  3.0
12.73          1.00  NaN
13.08          1.47  NaN
13.40          1.54  NaN
23.00           NaN  4.0
33.00           NaN  4.0

一种解决方法是为每个唯一的实验值选择数据,然后将所有这些数据连接起来:

pd.concat([d.loc[d.experiment.eq(c), ['x_values', 'y_values']].rename(columns={'y_values': c}) for c in d.experiment.unique()])

结果:

x_values     e    f
0     13.40  1.54  NaN
1     13.08  1.47  NaN
2     12.73  1.00  NaN
3     12.00   NaN  2.0
4     33.00   NaN  4.0
5     23.00   NaN  4.0
6     12.00   NaN  3.0

您也可以直接分配新的变量并根据布尔掩码填充它们:

df=pd.DataFrame(
data={
'x_values':[13.4, 13.08, 12.73, 12., 33., 23., 12.],
'y_values': [1.54, 1.47,1.,2.,4.,4.,3.],
'experiment':['e', 'e', 'e', 'f', 'f','f','f']
}
)
df['e'] = df.loc[df['experiment'] == 'e', 'y_values']
df['f'] = df.loc[df['experiment'] == 'f', 'y_values']
df_final = df.drop(columns=['y_values', 'experiment']).set_index(['x_values'])
df_final

-------------------------------------------------
e    f
x_values        
13.40     1.54  NaN
13.08     1.47  NaN
12.73     1.00  NaN
12.00     NaN   2.0
33.00     NaN   4.0
23.00     NaN   4.0
12.00     NaN   3.0
-------------------------------------------------

如果列experiment有多个属性,则可以遍历所有惟一值:

for experiment in df['experiment'].unique():
df[experiment] = df.loc[df['experiment'] == experiment, 'y_values']
df_final = df.drop(columns=['y_values', 'experiment']).set_index(['x_values'])
df_final

,产生期望的输出。

这种方法似乎比@Stef提供的方法更有效。然而,随着代码行数的增加,

from time import time
first_approach = []
for i in range(1000):
start = time()
pd.concat([df.loc[df.experiment.eq(c), ['x_values', 'y_values']].rename(columns={'y_values': c}) for c in df.experiment.unique()]).set_index(['x_values'])
first_approach.append(time()-start)

second_approach = []
for i in range(1000):
start = time()
for experiment in df['experiment'].unique():
df[experiment] = df.loc[df['experiment'] == experiment, 'y_values']
df.drop(columns=['y_values', 'experiment']).set_index(['x_values'])
second_approach.append(time()-start)

print(f'Average Time First Approach:t{sum(first_approach)/len(first_approach):.5f}')
print(f'Average Time Second Approach:t{sum(second_approach)/len(second_approach):.5f}')
--------------------------------------------
Average Time First Approach:    0.00403
Average Time Second Approach:   0.00205
--------------------------------------------

相关内容

最新更新