給定一個值(N, 2)陣列,我想要一個由.[start, stop] (M,)[np.arange(start[0], stop[0]), np.arange(start[1], stop[1], ..., np.arange(start[N - 1], stop[N - 1])]
例如,給定arr = np.array([[1, 3], [4, 5], [7, 8], [8, 10]]),我想要[1, 2, 4, 7, 8, 9]。
一種方法是使用 for 回圈:
arr = np.array([[1, 3], [4, 5], [7, 8], [8, 10]])
out = np.zeros(0, dtype=int)
for i in range(len(arr)):
out = np.append(out, np.arange(arr[i, 0], arr[i, 1]))
print(out)
結果:[1 2 4 7 8 9]。
有沒有更有效和/或更易讀的方法來做到這一點?
uj5u.com熱心網友回復:
這里有你需要的線路。
[item for start, stop in [[1, 3], [4, 5], [7, 8], [8, 10]] for item in range(start, stop)]
您可以處理普通串列來實作這一點。(不要過度使用 numpy,python vanilla 也不錯!)
對于少量資料,numpy 匯入不值得!
平均執行時間:
import time
import numpy as np
n = 10000
m = 10
in_data = [[i, i m] for i in range(n)]
t0 = time.time()
[item for sublist in [range(start, stop) for start, stop in in_data] for item in sublist]
print(time.time() - t0) # 0.006821393966674805 s
t0 = time.time()
[item for start, stop in in_data for item in range(start, stop)]
print(time.time() - t0) # 0.00554966926574707 s
t0 = time.time()
arr = np.array(in_data)
out = np.zeros(0, dtype=int)
for i in range(len(arr)):
out = np.append(out, np.arange(arr[i, 0], arr[i, 1]))
print(time.time() - t0) # 0.43521547317504883 s
uj5u.com熱心網友回復:
使用串列理解來收集 aranges,然后加入它們:
In [214]: alist = [[1, 3], [4, 5], [7, 8], [8, 10]]
In [215]: [np.arange(start,stop) for start,stop in alist]
Out[215]: [array([1, 2]), array([4]), array([7]), array([8, 9])]
In [216]: np.hstack(_)
Out[216]: array([1, 2, 4, 7, 8, 9])
有一個hstack使用索引語法的版本:
In [217]: np.r_[1:3, 4:5, 7:8, 8:10]
Out[217]: array([1, 2, 4, 7, 8, 9])
它將切片轉換為arange呼叫。它很緊湊,但它不容易與預定義的串列一起使用。
請注意,我從一個串列開始。對于這種迭代,從 (n,2) 陣列開始并不是更好。
使用預定義串列,首先創建一個元組:
In [225]: tup = tuple([slice(start,stop) for start, stop in alist])
In [226]: tup
Out[226]: (slice(1, 3, None), slice(4, 5, None), slice(7, 8, None), slice(8, 10, None))
In [227]: np.r_[tup]
Out[227]: array([1, 2, 4, 7, 8, 9])
無論如何,沒有一種方法可以通過一次呼叫生成多個 arange。如果 aranges 的長度都相同,則可以使用np.linspace,但如果它們的長度非常長,則不能使用。
我們盡量避免重復np.append。不如list append。
對于此示例,純串列方法要快得多:
In [230]: timeit [item for start, stop in alist for item in range(start, stop)]
1.53 μs ± 26.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [231]: timeit np.hstack([np.arange(start,stop) for start,stop in alist])
12.7 μs ± 58.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
如果單個范圍變得更長,則陣列方法可能會更快,但如果范圍總數增加,則不會改進。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/398139.html
下一篇:逐行條件組合陣列
