2 回答

TA貢獻1796條經驗 獲得超4個贊
第 1 部分:Pandas 和(也許)Numpy
比較您的method1b和method2:
method1b生成一個DataFrame,這可能是你想要的,
method2生成一個Numpy 數組,因此要獲得完全可比較的結果,您應該隨后從中生成一個DataFrame。
所以我將您的方法2更改為:
def method2():
masking = array_condition != 1
array1_new = array1[masking]
array2_new = array2[masking]
array3_new = array3[masking]
array_condition_new = array_condition[masking]
df_new = pd.DataFrame({ 'array_condition': array_condition[masking],
'array1': array1_new, 'array2': array2_new, 'array3': array3_new})
然后比較執行時間(使用%timeit)。
結果是我的method2 (擴展)版本的執行時間 比method1b長約5%(請自行檢查)。
所以我的觀點是,只要是單一的操作,可能還是和Pandas在一起比較好。
但是,如果您想在源 DataFrame 上按順序執行幾個操作和/或您對Numpy數組的結果感到滿意,那么值得:
調用
arr = df.values
以獲取底層Numpy數組。使用Numpy方法對其執行所有必需的操作。
(可選)從最終結果創建一個 DataFrame。
我嘗試了method1b的Numpy版本:
def method3(): a = df.values arr = a[a[:,0] != 1]
但執行時間要長約40%。
原因可能是Numpy數組具有相同類型的所有元素,因此array_condition列被強制浮動,然后創建整個Numpy數組,這需要一些時間。
第 2 部分:Numpy 和 Numba
要考慮的替代方法是使用Numba包 - 一種即時 Python 編譯器。
我做了這樣的測試:
創建了一個Numpy數組(作為初步步驟):
a = df.values
原因是 JIT 編譯的方法能夠使用Numpy方法和類型,但不能使用Pandas的方法和類型。
為了執行測試,我使用了與上面幾乎相同的方法,但使用了@njit注釋(需要來自 numba import njit):
@njit def method4(): arr = a[a[:,0] != 1]
這次:
執行時間約為method1b時間的 45% 。
但由于
a = df.values
已經在測試循環之前執行過,因此這個結果是否與之前的測試有可比性存在疑問。
無論如何,自己嘗試Numba,也許這對您來說是一個有趣的選擇。

TA貢獻1824條經驗 獲得超6個贊
您可能會發現在這里使用numpy.where很有用。它將布爾掩碼轉換為數組索引,使生活更便宜。將其與 numpy.vstack 結合可以實現一些內存便宜的操作:
def method3():
wh = np.where(array_condition == 1)
return np.vstack(tuple(col[wh] for col in (array1, array2, array3)))
這給出了以下時間:
>>> %timeit method2()
180 ms ± 6.66 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
>>> %timeit method3()
96.9 ms ± 2.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
元組解包允許該操作在內存上相當輕,因為當對象被 vstack-ed 重新組合在一起時,它會更小。如果您需要直接從 DataFrame 中獲取列,則以下代碼段可能有用:
def method3b():
wh = np.where(array_condition == 1)
col_names = ['array1','array2','array3']
return np.vstack(tuple(col[wh] for col in tuple(df[col_name].to_numpy()
for col_name in col_names)))
這允許人們從 DataFrame 中按名稱獲取列,然后在運行中對這些列進行元組解包。速度差不多:
>>> %timeit method3b()
96.6 ms ± 3.09 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
添加回答
舉報