np.power
là universal function (ufunc). Các hàm này có thể được sử dụng trên các scalars và mảng có nhiều kiểu dữ liệu khác nhau, nhưng trước tiên phải kiểm tra kiểu giá trị đầu vào để chúng có thể xác định vòng lặp nội bộ để sử dụng để tạo ra các giá trị đầu ra phù hợp.
Nếu loại đầu vào không ánh xạ tới bất kỳ vòng lặp được xác định trước của ufunc, thì ufunc sẽ cố gắng cast the input values to suitable types (trừ khi được thông báo khác). Việc kiểm tra và chuyển đổi các giá trị đầu vào này có chi phí hiệu năng được liên kết với nó, giải thích thời gian được quan sát trong câu hỏi.
Thuộc tính types
của ufunc cho biết cách các kiểu dữ liệu đầu vào sẽ ánh xạ tới kiểu dữ liệu đầu ra. Dưới đây là danh sách các ánh xạ cho np.power
:
>>> np.power.types # 'input input -> output'
['bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L', 'qq->q',
'QQ->Q', 'ee->e', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D', 'GG->G', 'OO->O']
số Floating-point thuộc về mã ký tự 'g'
, Python số nguyên thuộc về 'l'
. Danh sách đầy đủ các mã ký tự này có thể được tìm thấy here.
Lưu ý rằng đối với ufunc này, các kiểu dữ liệu của hai giá trị đầu vào phải giống nhau. Ví dụ: không có ánh xạ cho kết hợp các kiểu dữ liệu đầu vào là float
và int
.
Nhưng chúng tôi vẫn có thể cung cấp cho np.power
các kiểu dữ liệu khác nhau và để cho nó truyền các giá trị cho các kiểu dữ liệu thích hợp. Đối với một float
và một int
, một số float64
được trả về:
>>> np.power(3.71242, 7).dtype
dtype('float64')
Ở trên bạn có thể thấy rằng các đầu vào chỉ mà bản đồ để mã float64
nhân vật g
là hai g
giá trị khác: 'gg->g'
.
Vì vậy, đằng sau hậu trường, np.power(3.71242, 7)
đã lấy một mã số float
và Python int
và phải quyết định xem nó có thể khôi phục lại an toàn và loại nào. Giá trị int
được quảng cáo an toàn cho loại phao g
. Sau đó, ufunc biết vòng lặp nào để chạy và trả lại giá trị g
khác.
Vì lý do này, không trộn các kiểu dữ liệu đầu vào dẫn đến hiệu suất tốt hơn cho np.power
.
Nếu tôi đã phải mạo hiểm một dự đoán, numpy hy vọng một phao nhưng nhận được một int và cần thiết để chuyển đổi. –
@JeffMercado ý tưởng thú vị --- nhưng nó dường như không thêm lên: "% timeit -n 100000 -r 10 if (type (2) == int): float (2)" ==> "100000 vòng lặp, tốt nhất là 10: 571 ns trên mỗi vòng lặp " – DilithiumMatrix
Tôi nghi ngờ rằng một số mũ int gây ra phép nhân thực tế trong khi một số mũ nổi gây ra việc sử dụng các bản ghi. –