python - Pandas 计数值大于最后 n 行中的当前行

标签 python pandas dataframe

如何获取最后n行中大于当前行的值的个数?

假设我们有一个数据框如下:

    col_a
0    8.4
1   11.3
2    7.2
3    6.5
4    4.5
5    8.9

我正在尝试获取一个表格,例如下面的 n=3。

    col_a   col_b
0     8.4       0
1    11.3       0
2     7.2       2
3     6.5       3
4     4.5       3
5     8.9       0

提前致谢。

最佳答案

在 pandas 中最好不要循环因为慢,这里最好使用 rolling具有自定义功能:

n = 3
df['new'] = (df['col_a'].rolling(n+1, min_periods=1)
                        .apply(lambda x: (x[-1] < x[:-1]).sum())
                        .astype(int))
print (df)
   col_a  new
0    8.4    0
1   11.3    0
2    7.2    2
3    6.5    3
4    4.5    3
5    8.9    0

如果性能很重要,请使用 strides :

n = 3
x = np.concatenate([[np.nan] * (n), df['col_a'].values])

def rolling_window(a, window):
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    strides = a.strides + (a.strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
arr = rolling_window(x, n + 1)

df['new'] = (arr[:, :-1] > arr[:, [-1]]).sum(axis=1)
print (df)
   col_a  new
0    8.4    0
1   11.3    0
2    7.2    2
3    6.5    3
4    4.5    3
5    8.9    0

性能:这里使用了perfplot在小窗口 n = 3 中:

g1

np.random.seed(1256)
n = 3

def rolling_window(a, window):
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    strides = a.strides + (a.strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)

def roll(df):
    df['new'] = (df['col_a'].rolling(n+1, min_periods=1).apply(lambda x: (x[-1] < x[:-1]).sum(), raw=True).astype(int))
    return df

def list_comp(df):
    df['count'] = [(j < df['col_a'].iloc[max(0, i-3):i]).sum() for i, j in df['col_a'].items()]
    return df

def strides(df):
    x = np.concatenate([[np.nan] * (n), df['col_a'].values])
    arr = rolling_window(x, n + 1)
    df['new1'] = (arr[:, :-1] > arr[:, [-1]]).sum(axis=1)
    return df


def make_df(n):
    df = pd.DataFrame(np.random.randint(20, size=n), columns=['col_a'])
    return df

perfplot.show(
    setup=make_df,
    kernels=[list_comp, roll, strides],
    n_range=[2**k for k in range(2, 15)],
    logx=True,
    logy=True,
    xlabel='len(df)')

另外我很好奇在大窗口下的性能,n = 100:

g2

关于python - Pandas 计数值大于最后 n 行中的当前行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51039857/

相关文章:

python - Gmail 不处理通过 API 发送的回复

python - Python 是否支持自由间距的正则表达式?

传入文件路径、文件名或文件对象的 Python 约定

python - 从 Pandas 数据框中选择时的内存优化

html - python color entire pandas dataframe rows 基于列值

python - 将 2 个数据帧与索引连接为字符串列表时出错

python - 不满足条件时重置 pandas cumsum

python - Pandas 到 Excel(合并标题列)

python - 根据值的计数在数据框中删除列

Python:如何在由数组和 NaN 组成的数据帧(panda)中建立索引