다음 2 열 배열이 주어지면 첫 번째 열의 "edges"에 해당하는 항목을 두 번째 열에서 선택하려고합니다. 이것은 단지 예일뿐입니다. 사실 a
은 잠재적으로 수백만 개의 행을 가질 수 있습니다. 따라서, 가능한 한 빨리이 작업을 수행하고 중간 결과를 만들지 않고 작업하고 싶습니다.중간 색인 배열없이 numpy 배열에서 빠른 방법 선택
import numpy as np
a = np.array([[1,4],[1,2],[1,3],[2,6],[2,1],[2,8],[2,3],[2,1],
[3,6],[3,7],[5,4],[5,9],[5,1],[5,3],[5,2],[8,2],
[8,6],[8,8]])
즉 I는 결과를 어디서 찾을 a[:,0]
변화에 대응 a[:,1]
항목이다
desired = np.array([4,6,6,4,2])
원한다. 솔루션입니다
하나, np.array([6,6,4,2])
제공
b = a[(a[1:,0]-a[:-1,0]).nonzero()[0]+1, 1]
, 나는 단순히 첫 번째 항목, 아무 문제를 앞에 추가 할 수있다. 그러나 첫 번째 항목의 인덱스 중간 배열을 만듭니다. 나는 지능형리스트를 사용하여 중간을 피할 수 :
는c = [a[i+1,1] for i,(x,y) in enumerate(zip(a[1:,0],a[:-1,0])) if x!=y]
이것은 또한 [6,6,4,2]
을 제공합니다. 생성기 기반의 zip
(파이썬 3에서는 true)을 가정하면, 이것은 중간 표현을 생성 할 필요가 없으며 매우 메모리 효율적이어야합니다. 그러나 내부 루프는 numpy가 아니므로 나중에 numpy 배열로 되돌려 야하는 목록을 생성해야합니다.
메모리 효율이 c
인 numpy 전용 버전을 사용할 수 있지만 속도 효율성은 b
입니까? 이상적으로 한 번만 a
이상의 패스가 필요합니다.
(a
이 매우 큰 경우를 제외하고 속도를 측정하는 것은, 많은 여기에 도움이되지 않습니다, 그래서, 난 그냥 효율적 이론적으로 빠르고 메모리 무언가를 원하는이 벤치마킹을 귀찮게하지 않을 것입니다. 예를 들어, 당신은 할 수 있습니다 a
의 가정 행은 파일에서 스트리밍 및 액세스에 느린있다 - 그것은 a
이상의 두 번째 랜덤 액세스 패스를 필요로 한, b
솔루션을 방지하는 또 다른 이유)
편집 :. 방법은 큰 a
를 생성하는 테스트 용 매트릭스 :
from itertools import repeat
N, M = 100000, 100
a = np.array(zip([x for y in zip(*repeat(np.arange(N),M)) for x in y ], np.random.random(N*M)))
좀 더 일반적인 질문은 간단히 "numpy 배열보다 스트리밍 (생성기와 같은) 작업을 수행하려면 어떻게해야합니까?"라고 생각합니다. (목록으로 변환하지 않아도됩니다!) – Steve
* "... 가능한 한 빨리, 중간 결과를 만들지 않고 ..."* 때로는 상충되는 목표입니다. 더 중요한 것, 최고의 성능 또는 메모리 사용 최소화 –
글쎄요, "메모리 낭비"에 관한 것이 아니라, 메모리에 맞지 않는 배열 크기로 작동 할 수 있다는 것입니다. 속도를 너무 많이 희생하지는 않습니다. (예 : 메모리 매핑 된 파일의 배열) numpy.fromiter로 변환하면 속도가 10 배 희생 된 것처럼 보입니다. – Steve