Hãy thử điều này cho chính mình:Tại sao DataFrame.loc [[1]] chậm hơn 1,800x so với df.ix [[1]] và 3,500x so với df.loc [1]?
import pandas as pd
s=pd.Series(xrange(5000000))
%timeit s.loc[[0]] # You need pandas 0.15.1 or newer for it to be that slow
1 loops, best of 3: 445 ms per loop
Cập nhật: đó là a legitimate bug in pandas rằng có lẽ đã được giới thiệu trong 0.15.1 vào tháng năm 2014 hoặc lâu hơn. Giải pháp thay thế: chờ bản phát hành mới trong khi sử dụng phiên bản cũ của gấu trúc; có được một nhà phát triển tiên tiến. phiên bản từ github; tự sửa đổi một dòng trong bản phát hành pandas
; tạm thời sử dụng .ix
thay vì .loc
.
Tôi có một DataFrame với 4,8 triệu hàng, và chọn một hàng duy nhất sử dụng .iloc[[ id ]]
(với một danh sách phần tử đơn) mất 489 mili giây, gần như nửa giây, chậm hơn so với các giống .ix[[ id ]]
1,800x lần, và 3.500 lần chậm hơn.iloc[id]
(chuyển id dưới dạng giá trị, không phải dưới dạng danh sách). Để công bằng, .loc[list]
mất khoảng thời gian đó bất kể độ dài của danh sách nhưng tôi không muốn chi tiêu 489 ms trên đó, đặc biệt là khi .ix
nhanh hơn hàng nghìn lần và tạo kết quả giống nhau. Đó là sự hiểu biết của tôi rằng .ix
được cho là chậm hơn, phải không?
Tôi đang sử dụng gấu trúc 0,15,1. Hướng dẫn tuyệt vời trên Indexing and Selecting Data gợi ý rằng .ix
bằng cách nào đó tổng quát hơn và có lẽ chậm hơn, so với .loc
và .iloc
. Cụ thể, nó cho biết
Tuy nhiên, khi trục là số nguyên, truy cập dựa trên nhãn duy nhất và không hỗ trợ truy cập vị trí. Do đó, trong các trường hợp như vậy, thường là tốt hơn để rõ ràng và sử dụng .iloc hoặc .loc.
Dưới đây là một phiên ipython với các tiêu chuẩn:
print 'The dataframe has %d entries, indexed by integers that are less than %d' % (len(df), max(df.index)+1)
print 'df.index begins with ', df.index[:20]
print 'The index is sorted:', df.index.tolist()==sorted(df.index.tolist())
# First extract one element directly. Expected result, no issues here.
id=5965356
print 'Extract one element with id %d' % id
%timeit df.loc[id]
%timeit df.ix[id]
print hash(str(df.loc[id])) == hash(str(df.ix[id])) # check we get the same result
# Now extract this one element as a list.
%timeit df.loc[[id]] # SO SLOW. 489 ms vs 270 microseconds for .ix, or 139 microseconds for .loc[id]
%timeit df.ix[[id]]
print hash(str(df.loc[[id]])) == hash(str(df.ix[[id]])) # this one should be True
# Let's double-check that in this case .ix is the same as .loc, not .iloc,
# as this would explain the difference.
try:
print hash(str(df.iloc[[id]])) == hash(str(df.ix[[id]]))
except:
print 'Indeed, %d is not even a valid iloc[] value, as there are only %d rows' % (id, len(df))
# Finally, for the sake of completeness, let's take a look at iloc
%timeit df.iloc[3456789] # this is still 100+ times faster than the next version
%timeit df.iloc[[3456789]]
Output:
The dataframe has 4826616 entries, indexed by integers that are less than 6177817
df.index begins with Int64Index([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], dtype='int64')
The index is sorted: True
Extract one element with id 5965356
10000 loops, best of 3: 139 µs per loop
10000 loops, best of 3: 141 µs per loop
True
1 loops, best of 3: 489 ms per loop
1000 loops, best of 3: 270 µs per loop
True
Indeed, 5965356 is not even a valid iloc[] value, as there are only 4826616 rows
10000 loops, best of 3: 98.9 µs per loop
100 loops, best of 3: 12 ms per loop
Lưu ý rằng việc sử dụng '[[id]]' và '[id]' không tương đương. '[id]' sẽ trả về một chuỗi, nhưng '[[id]]' sẽ trả về một DataFrame một hàng. – BrenBarn
@BrenBarn, vâng, điều này giải thích sự khác biệt cho '.ix': 141 µs so với 270 µs. Nhưng tại sao '.loc [[id]]' quá chậm? – osa