lia*_*ang 28 indexing numpy unique python-2.7
假设我有
>>> v
array([1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 3, 4, 3, 4, 3, 4, 5, 5, 5])
Run Code Online (Sandbox Code Playgroud)
是否有一种有效的numpy方法来查找值变化的每个索引?例如,我想要一些结果,比如
>>> index_of_changed_values(v)
[0, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16]
Run Code Online (Sandbox Code Playgroud)
如果使用一些numpy例程是不可能的,那么在python中执行它的快速方法是什么?因为我是一个笨拙的初学者,所以我可以参考一些好的numpy教程.
kit*_*ith 47
您可以通过将每个元素与其邻居进行比较来获得numpy中的此功能;
v[:-1] != v[1:]
array([False, False, False, False, True, False, False, True, True,
True, True, True, True, True, True, True, False, False], dtype=bool)
Run Code Online (Sandbox Code Playgroud)
获取你使用"where"函数的索引
np.where(v[:-1] != v[1:])[0]
array([ 4, 7, 8, 9, 10, 11, 12, 13, 14, 15])
Run Code Online (Sandbox Code Playgroud)
从这里开始,您可以添加第一个元素并添加一个元素以获得您在问题中使用的相同索引方案.
类似于@kith 答案,但需要较少的结果按摩:
np.where(np.roll(v,1)!=v)[0]
Run Code Online (Sandbox Code Playgroud)
无需添加 0 或添加 1。示例:
>>> v=np.array([1, 1, 1, 2, 2, 3, 3, 4, 4, 4])
>>> np.where(np.roll(v,1)!=v)[0]
array([0, 3, 5, 7])
Run Code Online (Sandbox Code Playgroud)
编辑:正如@Praveen 提到的,当最后一个元素和第一个元素相等时,这会失败。
很好的问题和答案!
\n我正在使用一个向量,该向量包含大约 100 万个从 1 到 100,000 的单调非递减整数(例如 [1, 1, 1, 2, 3, 3, 4, ..., 100000]
)。对于这个数据集,上面讨论的 2 个习惯用法以及是否使用 prepend kwarg 之间似乎存在明显的性能差异:
%timeit np.where(np.diff(v, prepend=np.nan)) \n15.3 ms \xc2\xb1 113 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 100 loops each)\n\n%timeit np.where(np.diff(v))[0] + 1 \n7.41 ms \xc2\xb1 72 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 100 loops each)\n\n%timeit np.where(v[:-1] != v[1:])[0] + 1 \n2.85 ms \xc2\xb1 41.7 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 100 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n因此,与使用带前缀 kwarg 的 diff() 相比,花式索引调用速度快 5 倍,比使用不带前缀的 diff 快两倍以上(无论如何在我古老的 MacBook Air 上)。对于大多数用例来说,这种性能差异并不重要,但我正在处理数千个这样的数据集(总共数十亿行),因此我需要牢记性能。
\n差不多十年后,但我今天遇到了这个。
@kith 的回答很好,但可能没有我们想要的那么整洁(还要考虑到答案中没有明确的步骤)。
完整形式的答案是,
v = np.array([1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 3, 4, 3, 4, 3, 4, 5, 5, 5])
np.concatenate((np.array([0]),np.where(v[:-1] != v[1:])[0]+1),axis=0)
Run Code Online (Sandbox Code Playgroud)
我更喜欢的一个选择是,
np.where(np.diff(v,prepend=np.nan))[0]
Run Code Online (Sandbox Code Playgroud)
这也返回
array([ 0, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16], dtype=int64)
Run Code Online (Sandbox Code Playgroud)
正如我所说,这个想法与@kith 的想法相同,但是,
v[:-1] != v[1:]
为np.diff()
,然后在np.where
数组中转换为布尔值,这没有太大变化,但看起来更整洁。np.nan
在做之前预先添加来完成的np.diff()
。diff 输出的第一个元素将是np.nan
,并且在 python np.nan 中总是评估True
. 归档时间: |
|
查看次数: |
11486 次 |
最近记录: |