Pandas累积中值

2024-05-23 17:25:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我在想,是否有熊猫等同于cumsum()或{}等中值:例如cummedian()。在

因此,如果我有,例如这个数据帧:

   a
1  5
2  7
3  6
4  4

我想要的是:

^{pr2}$

应输出:

5
6  
6 
5.5

Tags: 数据pr2cumsumcummedian
3条回答

一种快速求解特定累积中值的方法

In [1]: import timeit

In [2]: setup = """import bisect
   ...: import pandas as pd
   ...: def cummedian():
   ...:     l = []
   ...:     info = [0, True]
   ...:     def inner(n):
   ...:         bisect.insort(l, n)
   ...:         info[0] += 1
   ...:         info[1] = not info[1]
   ...:         median = info[0] // 2
   ...:         if info[1]:
   ...:             return (l[median] + l[median - 1]) / 2
   ...:         else:
   ...:             return l[median]
   ...:     return inner
   ...: df = pd.DataFrame({'a': range(20)})"""

In [3]: timeit.timeit("df['cummedian'] = df['a'].apply(cummedian())",setup=setup,number=100000)
Out[3]: 27.11604686321956

In [4]: timeit.timeit("df['expanding'] = df['a'].expanding().median()",setup=setup,number=100000)
Out[4]: 48.457676260100335

In [5]: 48.4576/27.116
Out[5]: 1.7870482372031273

您可以使用expanding.median-

df.a.expanding().median()

1    5.0
2    6.0
3    6.0
4    5.5
Name: a, dtype: float64

计时

^{pr2}$

胜利者以巨大的优势expanding.median。Divakar的方法是内存密集型的,在这种大小的输入下会遭受内存崩溃。在

我们可以用一个基于strides的函数创建一个填充nan的子数组,比如-

def nan_concat_sliding_windows(x):
    n = len(x)
    add_arr = np.full(n-1, np.nan)
    x_ext = np.concatenate((add_arr, x))
    strided = np.lib.stride_tricks.as_strided
    nrows = len(x_ext)-n+1
    s = x_ext.strides[0]
    return strided(x_ext, shape=(nrows,n), strides=(s,s))

样本运行-

^{pr2}$

因此,要获得数组x的滑动中值,我们需要一个向量化的解决方案,如-

np.nanmedian(nan_concat_sliding_windows(x), axis=1)

因此,最终的解决方案是-

In [54]: df
Out[54]: 
a
1  5
2  7
3  6
4  4

In [55]: pd.Series(np.nanmedian(nan_concat_sliding_windows(df.a.values), axis=1))
Out[55]: 
0    5.0
1    6.0
2    6.0
3    5.5
dtype: float64

相关问题 更多 >