在pandas裏,對於DataFrame,可以利用applymap(func)函數實現對DataFrame中每個元素進行函數func操作,而且相比於for loop,其性能會有較大的提升。而對於numpy中的ndarrray,沒有類似名稱的函數實現相同功能,但是有一個numpy.frompyfunc函數,其可以對一個python函數進行封裝,返回一個封裝後的函數,然後可以利用返回的封裝後的函數直接對ndarray進行操作,從而實現對ndarray中的每個元素實現相應的函數操作,這種方式相比於DataFrame的applymap函數,性能還有更進一步的提升。
如上圖所示,numpy.frompyfunc函數有三個參數,第一個參數爲func,表示傳入的python函數,nin表示func的輸入的參數,nout表示func輸出結果的個數。當func爲輸入爲1輸出也爲1的函數時,即nin=1,nout=1時,這時func就是一個元素級操作函數,可以實現類似DataFrame的applymap函數的功能;但func還可以是多輸入和輸出的函數,因此numpy.frompyfunc函數的功能實際上更爲強大。具體用法參考如下例子。
import numpy as np
arr=np.array([[1,2,3],[2,3,4]])
f1=np.frompyfunc(lambda x:x+1 if x<5 else x-1,1,1)
f2=np.frompyfunc(lambda x:(x+1,x-1),1,2)
f3=np.frompyfunc(lambda x,y:x+y,2,1)
f4=np.frompyfunc(lambda x,y:(x+y,x-y),2,2)
f1(arr)
# output:
# array([[2, 3, 4],
# [3, 4, 5]], dtype=object)
f2(arr)
# output:
# (array([[2, 3, 4],
# [3, 4, 5]], dtype=object),
# array([[0, 1, 2],
# [1, 2, 3]], dtype=object))
f3(arr,arr)
# output:
# array([[2, 4, 6],
# [4, 6, 8]], dtype=object)
f4(arr,arr)
# output:
# (array([[2, 4, 6],
# [4, 6, 8]], dtype=object),
# array([[0, 0, 0],
# [0, 0, 0]], dtype=object))
ar=np.array([1,2,3])
f4(arr,ar)
# output:
# (array([[2, 4, 6],
# [3, 5, 7]], dtype=object),
# array([[0, 0, 0],
# [1, 1, 1]], dtype=object))
從上面例子中可以看到,nin參數即是func的輸入參數的個數,同時也是返回的函數的參數個數,而且在返回的函數中的參數不一定的相同shape的,但shape必須兼容廣播操作,如f4(arr,ar)語句所示。