gpt4 book ai didi

python pandas从一系列 bool 值中获取索引边界

转载 作者:行者123 更新时间:2023-12-04 12:25:34 26 4
gpt4 key购买 nike

我正在尝试根据一些特征剪辑视频。
我目前的策略领先于 pandas每个帧的一系列 bool 值,按时间戳索引。 True保留它,False倾倒它。

当我计划剪切视频时,我需要从这个列表中提取边界,以便我可以告诉 fmpeg 我想从主视频中提取的部分的开始和结束。

涂总结:

我有一个 pandas看起来像这样的系列:

acquisitionTs
0.577331 False
0.611298 False
0.645255 False
0.679218 False
0.716538 False
0.784453 True
0.784453 True
0.818417 True
0.852379 True
0.886336 True
0.920301 True
0.954259 False
...
83.393376 False
83.427345 False
dtype: bool

(出于演示原因被截断,但时间戳通常从 0 开始)

我需要得到 True 的边界序列,所以在这个例子中我应该得到 [[t_0,t_1],[t_2,t_3]n, ... [t_2n-1,t_2n]] , 与 t_0 = 0.784453t_1 = 0.920301如果我有 n True的不同序列在我的 Pandas 系列中。

现在这个问题看起来很简单,实际上你可以将序列移动一个并在 之间做一个异或来得到一个 bool 值列表 True为边界而存在
e = df.shift(periods=1, freq=None, axis=0)^df
print(e[e].index)

( df 是 Pandas 系列)
还有一些工作要做,比如确定第一个元素是上升沿还是下降沿,但是这个 hack 有效。

然而,这似乎不是很pythonic。其实问题就这么简单我相信 pandas肯定有什么地方, numpy甚至 python一个预先构建的函数,它可以很好地适应单个函数调用,而不是像上面那样的 hack。 groupby功能似乎很有前途,但我以前从未使用过它。

这样做的最佳方法是什么?

最佳答案

您可以使用 scipy.ndimage.label 识别 True 的簇s:

In [102]: ts
Out[102]:
0.069347 False
0.131956 False
0.143948 False
0.224864 False
0.242640 True
0.372599 False
0.451989 False
0.462090 False
0.579956 True
0.588791 True
0.603638 False
0.625107 False
0.642565 False
0.708547 False
0.730239 False
0.741652 False
0.747126 True
0.783276 True
0.896705 True
0.942829 True
Name: keep, dtype: bool

In [103]: groups, nobs = ndimage.label(ts); groups
Out[103]: array([0, 0, 0, 0, 1, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3], dtype=int32)

一旦您拥有 groups数组,您可以使用 groupby/agg 找到相关的时间:
    result = (df.loc[df['group'] != 0]
.groupby('group')['times']
.agg({'start':'first','end':'last'}))

例如,
import numpy as np
import pandas as pd
import scipy.ndimage as ndimage
np.random.seed(2016)

def make_ts(N, ngroups):
times = np.random.random(N)
times = np.sort(times)
idx = np.sort(np.random.randint(N, size=(ngroups,)))
arr = np.zeros(N)
arr[idx] = 1
arr = arr.cumsum()
arr = (arr % 2).astype(bool)
ts = pd.Series(arr, index=times, name='keep')
return ts

def find_groups(ts):
groups, nobs = ndimage.label(ts)
df = pd.DataFrame({'times': ts.index, 'group': groups})
result = (df.loc[df['group'] != 0]
.groupby('group')['times']
.agg({'start':'first','end':'last'}))
return result

ts = make_ts(20, 5)
result = find_groups(ts)

产量
          start       end
group
1 0.242640 0.242640
2 0.579956 0.588791
3 0.747126 0.942829

要以列表形式获取开始和结束时间,您可以使用:
In [125]: result.values.tolist()
Out[125]:
[[0.24264034406127022, 0.24264034406127022],
[0.5799564094638113, 0.5887908182432907],
[0.7471260123697537, 0.9428288694956402]]

使用 ndimage.label很方便,但请注意,也可以在没有 scipy 的情况下进行计算:
def find_groups_without_scipy(ts):
df = pd.DataFrame({'times': ts.index, 'group': (ts.diff() == True).cumsum()})
result = (df.loc[df['group'] % 2 == 1]
.groupby('group')['times']
.agg({'start':'first','end':'last'}))
return result

这里的主要思想是为 True 的簇找到标签。 s 使用 (ts.diff() == True).cumsum() . ts.diff() == True给出与 ts.shift() ^ ts 相同的结果,但速度要快一些。取累积和(即调用 cumsum )对待 True等于 1 和 False因为等于0,所以每次都是 True遇到累积总和增加 1。因此,每个集群都被标记为不同的数字:
In [111]: (ts.diff() == True).cumsum()
Out[111]:
0.069347 0
0.131956 0
0.143948 0
0.224864 0
0.242640 1
0.372599 2
0.451989 2
0.462090 2
0.579956 3
0.588791 3
0.603638 4
0.625107 4
0.642565 4
0.708547 4
0.730239 4
0.741652 4
0.747126 5
0.783276 5
0.896705 5
0.942829 5
Name: keep, dtype: int64

关于python pandas从一系列 bool 值中获取索引边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38917076/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com