我有一个大的数据框(大约3GB),我想计算几列上的一组中位数,但当我有偶数个值时,我不想取两个中心元素的平均值,但是获取这两个值中的最低值。 我知道如何做正常的中位数,这是重现我的问题的示例:
import pandas as pd
data = {'idx': [1,1,1,1,1,2,2,2,2,2,2,3,3,3,4,4,5],
'value': [5,12,7,8,10,3,8,4,6,1,19,5,10,12,3,8,14]
}
df = pd.DataFrame (data, columns = ['idx','value'])
df['median']=df.groupby(['idx'])['value'].transform(np.median)
print(df)
idx value median
0 1 5.0 8.0
1 1 12.0 8.0
2 1 7.0 8.0
3 1 8.0 8.0
4 1 10.0 8.0
5 2 3.0 5.0
6 2 8.0 5.0
7 2 4.0 5.0
8 2 6.0 5.0
9 2 1.0 5.0
10 2 19.0 5.0
11 3 5.0 10.0
12 3 10.0 10.0
13 3 12.0 10.0
14 4 3.0 5.5
15 4 8.0 5.5
16 5 14.0 14.0
但正如我所说,我不希望有这样的结果。
我想要:
我可以使用下面的函数来做到这一点,但性能非常低:
def calcul_median(x):
a=x['values'].values.tolist()
if len(a)%2==1:
a = np.median(a)
elif len(a)==0:
a=0
else:
a.sort()
a =a[int((len(a)/2)-1)]
x['median'] =a
return x
df2=df.groupby(['idx']).apply(calcul_median)
这个函数可以工作,但是非常慢(比中位数慢 50 倍)。
编辑
函数 stats.median_low 可以做到这一点,但速度也很慢。 使用 numpy 的 3 秒 vs 使用统计数据的 52 秒。
我尝试了另一个带有 argpartition 的函数
def calcul_tps_medianv2(x):
a=x['dureetrajet'].values.tolist()
if len(a)%2==1:
a = np.median(a)
elif len(a)==0:
a=0
else:
a[np.argpartition(a,int((len(a)/2)-1))[int((len(a)/2)-1)]]
x['median'] =a
return x
但这比统计解决方案慢。
您有任何加快此功能的想法或任何其他想法吗?感谢您的帮助。
标准库包含一个median_low()函数,它的作用只是 那个。
蒂姆·皮茨克