2012-03-31 2 views

답변

6

를 대신 iterrows 방법을 사용하여 두 배 빠른 결과를 통해 얻을 수 있습니다 어디에 :

In [117]: timeit max(row['timestamp'] for row in table.iterrows(stop=1000000)) 
1 loops, best of 3: 1 s per loop 

In [118]: timeit max(row['timestamp'] for row in table.where('(timestamp<=Tf)')) 
1 loops, best of 3: 2.21 s per loop 

In [120]: timeit max(frames.cols.timestamp[:1000000]) 
1 loops, best of 3: 974 ms per loop 

In [121]: timeit np.max(frames.cols.timestamp[:1000000]) 
1 loops, best of 3: 876 ms per loop 

참고 Tf를는 1,000,000 엔트리 O 인 위 f 그 열 (Float64)입니다.

질문은 비교 검사를 요구하지 않으므로 어디서 검사를 할 수 있습니까? 질문에 제안 된 방법 (numpy 배열로 데이터로드)은 여전히 ​​다소 빠릅니다 (단, 차이점은 3 % 미만이고 더 큰 데이터 세트의 경우 더 작아 지므로 10^7 행 이상을 테스트하지 않았습니다. 최상의 결과 numpy 기능을 사용하는 곳을 찾았습니다 (위 참조).

나는 또한보다 효율적인 방법을 배우게되어 기쁩니다.

table.cols.timestamp.createCSIndex() 

일단 색인, 최대를 얻는 것은 거의 순간입니다 :

1

High Performance Data Management with PyTables & Family (PDF)에서 :

e = sum(row['col1'] for row in table.where(3<table.cols.col2<=20)) 

max() 사용하려면이 수정 : 내가 만든 한 테스트에서

e = max(row['col1'] for row in table.where(3<table.cols.col2<=20)) 
+0

이것은 작동하지만 이것은 완전히 커널에있는 것이 아닙니다. where 절이 큰 집합을 반환하면 큰 배열에서 max()를 실행하는 것과 같습니다. 이것이 더 이상 최적화 될 수 있습니까? – jagguli

+0

PyTables는 기본적으로 집계 함수를 지원하지 않습니다. 'table.where()'는 반복자를 반환하므로 전체 테이블을 메모리로 가져 가지 않습니다. 내부적으로, 그것은 한 번에 하나의 레코드를 읽고 그것을 산출합니다. "커널에서"는'table.where()'에 전달 된 조건에만 적용됩니다. –

2

내가이 일을 발견했습니다 가장 빠른 방법은 당신이 관심있는 COLS에 테이블을 인덱싱하는 것입니다

max_timestamp = table.cols.timestamp[table.colindexes['timestamp'][-1]] 

이것은 타임 스탬프 열 (table.colindexes['timestamp'][-1])에 대한 테이블의 Index 개체에서 마지막 (가장 큰 타임 스탬프에 해당) 행 인덱스를 가져온 다음 해당 열 참조로 인덱싱하여 가리키는 행을 가져옵니다. table.cols.timestamp).