获得少于或等于系列的条目数

时间:2019-04-08 09:47:26

标签: pandas

我想使所有元素的数量小于或等于pandas.Series中的每个条目,例如:

if __name__ == '__main__':
    import pandas as pd
    a = pd.Series(data=[4,7,3,5,2,1,1,6])
    le = pd.Series(data=[a[a <= i].count() for i in a])
    print(le)

结果:

0    5
1    8
2    4
3    6
4    3
5    2
6    2
7    7
dtype: int64

对于大型数据集,Series中是否有函数或更好的方法呢?

3 个答案:

答案 0 :(得分:3)

更快的解决方案-将Series转换为numpy array并通过广播到2d数组进行比较,最后将True的值乘以sum

b = a.values
#pandas 0.24+
#b = a.to_numpy()
le = pd.Series((b <= b[:, None]).sum(axis=1), index=a.index)

详细信息

print (b <= b[:, None])
[[ True False  True False  True  True  True False]
 [ True  True  True  True  True  True  True  True]
 [False False  True False  True  True  True False]
 [ True False  True  True  True  True  True False]
 [False False False False  True  True  True False]
 [False False False False False  True  True False]
 [False False False False False  True  True False]
 [ True False  True  True  True  True  True  True]]

le = pd.Series([a.le(i).sum() for i in a])

le = a.apply(lambda i: a.le(i).sum())

print(le)
0    5
1    8
2    4
3    6
4    3
5    2
6    2
7    7
dtype: int64

性能

np.random.seed(2019)
N = 10**6
s = pd.Series(np.random.randint(100, size=N))
#print (s)

In [173]: %%timeit
     ...: b = a.values
     ...: le = pd.Series((b <= b[:, None]).sum(axis=1), index=a.index)
     ...: 
78.6 µs ± 510 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [174]: %%timeit
     ...: le = pd.Series([a.le(i).sum() for i in a])
     ...: 
3.22 ms ± 136 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [175]: %%timeit
     ...: le = a.apply(lambda i: a.le(i).sum())
     ...: 
3.35 ms ± 290 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [176]: %%timeit
     ...: a.apply(lambda x: a[a.le(x)].count())
     ...: 
     ...: 
5.41 ms ± 457 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [177]: %%timeit
     ...: le = pd.Series(data=[a[a <= i].count() for i in a])
     ...: 
4.91 ms ± 281 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

答案 1 :(得分:1)

您可以使用apply和lambda函数:

In [4]: a.apply(lambda x: a[a.le(x)].count())
Out[4]: 0    5
        1    8
        2    4
        3    6
        4    3
        5    2
        6    2
        7    7
        dtype: int64

答案 2 :(得分:0)

该问题将应用于大型数据集:

%timeit [(a.values <= x).sum() for x in a]
10000 loops, best of 3: 28.6 µs per loop

%timeit le = pd.Series(data=[a[a <= i].count() for i in a])
100 loops, best of 3: 2.74 ms per loop

%timeit a.apply(lambda x: a[a.le(x)].count())
100 loops, best of 3: 3.09 ms per loop

这意味着应用速度很慢,OP的方法也不是最好的。