2014-04-04 3 views
0

모두파이썬 코드를 최적화하는 방법

다음 파이썬 코드를 사용하여 일부 기능 값을 계산할 것입니다. 하지만 입력 크기가 너무 크기 때문에 시간이 많이 걸립니다. 코드 최적화를 도와주세요.

leaving_volume=len([x for x in pickup_ids if x not in dropoff_ids]) 
    arriving_volume=len([x for x in dropoff_ids if x not in pickup_ids]) 
    transition_volume=len([x for x in dropoff_ids if x in pickup_ids]) 

    union_ids=list(set(pickup_ids + dropoff_ids)) 
    busstop_ids=[x for x in union_ids if self.geoitems[x].fare>0] 
    busstop_density=np.sum([Util.Geodist(self.geoitems[x].orilat, self.geoitems[x].orilng, self.geoitems[x].destlat, self.geoitems[x].destlng)/(1000*self.geoitems[x].fare) for x in busstop_ids])/len(busstop_ids) if len(busstop_ids) > 0 else 0 
    busstop_ids=[x for x in union_ids if self.geoitems[x].balance>0] 
    smartcard_balance=np.sum([self.geoitems[x].balance for x in busstop_ids])/len(busstop_ids) if len(busstop_ids) > 0 else 0 

안녕, 모든,

여기 내 수정 된 버전입니다. 내 GPS 추적 데이터에서이 코드를 실행합니다. 더 빠릅니다. 도움을

intersect_ids=set(pickup_ids).intersection(set(dropoff_ids)) 
union_ids=list(set(pickup_ids + dropoff_ids)) 
leaving_ids=set(pickup_ids)-intersect_ids 
leaving_volume=len(leaving_ids) 
arriving_ids=set(dropoff_ids)-intersect_ids 
arriving_volume=len(arriving_ids) 
transition_volume=len(intersect_ids) 

busstop_density=np.mean([Util.Geodist(self.geoitems[x].orilat, self.geoitems[x].orilng, self.geoitems[x].destlat, self.geoitems[x].destlng)/(1000*self.geoitems[x].fare) for x in union_ids if self.geoitems[x].fare>0]) 
if not busstop_density > 0: 
    busstop_density = 0 
smartcard_balance=np.mean([self.geoitems[x].balance for x in union_ids if self.geoitems[x].balance>0]) 
if not smartcard_balance > 0: 
    smartcard_balance = 0 

많은 감사합니다.

+0

np.sum이 목록에서 작동하는지 확실하지 않습니다. 또한, 파이썬 2.7 이하에서는 정수 나누기 (파이썬의 실제 버전을 모른다)를 사용합니다. 처음 세 표현은 두 세트의 차이점이며 한 세트 교차점은이를 사용합니다. 한 사이클 내에서 무엇이든하는 것은 그리 효율적이지 않습니다. 객체 목록 (geoitems) 대신 배열 또는 레코드 배열 사전을 사용하십시오. – Martin

답변

3

좀 파이썬 효율 퀴즈로, 발견 그냥 몇 가지 다음 in 연산자를 사용하여 회원 가입을 확인

if x not in dropoff_ids 

list보다 set에 더 효율적입니다. 그러나 for에서 list까지 반복하는 것은 아마도 set에서보다 효율적입니다. 따라서 처음 두 줄을 최대한 효율적으로 사용하려면 두 가지 유형의 데이터 구조를 사전에 준비해야합니다. 오히려 긴 list를 만들고 여기에서 set를 구성하는 것보다, 데이터를 결합하기 전에

list(set(pickup_ids + dropoff_ids)) 

그것은 당신의 세트를 생성하는 것이 더 효율적입니다. 다행히도 이미 주위에 set 버전이 이미있을 것입니다 (첫 번째 의견 참조)! 당신은 자신에게 질문을 요청해야 무엇보다도

:

내가 그들을 구성하는 데 걸리는 시간을 가치 추가 데이터 구조를 구성하여 저장 시간인가?

다음 하나 :

np.sum([...]) 

나는 list를 구성하고 이론적으로 만 code smell로 발전기를 필요로하는 기능을 적용하는 생각 파이썬에서 훈련을했습니다. 이것이 numpy에서 적용되는지 확실하지 않습니다. 왜냐하면 내가 기억하는 바로는 생성기에서 데이터를 가져 와서 numpy 구조로 저장하는 것이 완전히 어렵지 않기 때문입니다.

코드의 일부분 인 것처럼 보입니다. 당신이 정말로 효율성에 대해 염려한다면리스트보다는 numpy 배열을 사용하고 numpy의 내장 데이터 구조와 함수 내에서 가능하면 많은 것을 사용하는 것이 좋습니다. C에서 내장 된 파이썬 함수보다 원시 데이터 처리를 위해 최적화 된 가능성이 높습니다.

의 경우 실제로는의 효율성에 관심이 있습니다. C에서이 데이터 분석을 수행해야합니다. 특히 여기에 제시된 것보다 훨씬 많은 코드가없는 경우 번역하기가 꽤 쉬워.

0

나는이 게시물에서 yerning이 쓴 기계 만 지원할 수 있습니다.당신이 당신의 변수 pickup_ids 및 dropoff_ids 어쩌면 이미 다른 있습니다 NumPy와 배열 (있다면 그렇게 NumPy와로 전환을 생각하는 경우 수행

dropoff_ids = np.array(dropoff_ids, dtype='i') 
pickup_ids = np.array(pickup_ids, dtype='i') 

는 다음 기능 np.in1d ​​()있는 줄 것이다 사용할 수있다 당신은 (pickup_ids)는 단지 진정한 항목의 총 수를 얻을 수 이상의 요약 할 수있는 참/거짓 배열 어떻게 든

leaving_volume = (-np.in1d(pickup_ids, dropoff_ids)).sum() 
transition_volume= np.in1d(dropoff_ids, pickup_ids).sum() 
arriving_volume = (-np.in1d(dropoff_ids, pickup_ids)).sum() 

내가 = LEN을 transition_volume 느낌이를 -. arriving_volume하지만 난 100 % 확실하지 않다 지금 당장.

또 다른 기능 th at 당신이 유용하게 쓸 수있는 것은 np.unique()이다. 중복 엔트리를 없애고 배열을 배열로 바꾸는 것이 좋다.

관련 문제