pandas:只保留累积变化的每一行达到阈值?

时间:2016-09-11 01:47:13

标签: python pandas numpy

我有兴趣提取列的值累计上升至少5或累计下降至少5的行,然后得到这些累积变化的迹象,{{ 1}}。

例如,我们想要将其应用于以下列y

df = pd.DataFrame({'x': range(16), 'y': [1,10,14,12,13,9,4,2,6,7,10,11,16,17,14,11]})

它应该产生:

x   y        # up_or_down
1   10       # +1
6   4        # -1
10  10       # +1
12  16       # +1
15  11       # -1

我的数据框非常大,所以我希望有一个很好的矢量化方法,可以使用pandas的API本地执行此操作,而不是使用iterrows()循环使用它。

2 个答案:

答案 0 :(得分:2)

这是解决方案的核心

def big_diff(y):
    val = y.values
    r = val[0]
    for i, x in enumerate(val):
        d = r - x
        if abs(d) >= 5:
            yield i, 1 if d < 0 else -1
            r = x

然后你可以做这样的事情

slc = np.array(list(big_diff(df.y)))
df_slcd = pd.DataFrame(df.values[slc[:, 0]], df.index[slc[:, 0]], df.columns)
signs = pd.Series(slc[:, 1], df.index[slc[:, 0]], name='up_or_down')

df_slcd

enter image description here

signs

1     1
6    -1
10    1
12    1
15   -1
Name: up_or_down, dtype: int64
pd.concat([df_slcd, signs], axis=1)

enter image description here

答案 1 :(得分:1)

你不能通过暴露的标准函数pandas对它进行矢量化:动态找到从n-1th发现+/- 5移动的第n个点,它将取决于n-1的位置,它本身就是取决于n-2个第一个动态确定的点。因此,没有与滚动或扩展函数集关联的数学可以将您投射到需要此动态的向量空间中。所以你必须为你写迭代ad-hoc。