2 回答

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超4個(gè)贊
第 1 部分:Pandas 和(也許)Numpy
比較您的method1b和method2:
method1b生成一個(gè)DataFrame,這可能是你想要的,
method2生成一個(gè)Numpy 數(shù)組,因此要獲得完全可比較的結(jié)果,您應(yīng)該隨后從中生成一個(gè)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})
然后比較執(zhí)行時(shí)間(使用%timeit)。
結(jié)果是我的method2 (擴(kuò)展)版本的執(zhí)行時(shí)間 比method1b長(zhǎng)約5%(請(qǐng)自行檢查)。
所以我的觀點(diǎn)是,只要是單一的操作,可能還是和Pandas在一起比較好。
但是,如果您想在源 DataFrame 上按順序執(zhí)行幾個(gè)操作和/或您對(duì)Numpy數(shù)組的結(jié)果感到滿(mǎn)意,那么值得:
調(diào)用
arr = df.values
以獲取底層Numpy數(shù)組。使用Numpy方法對(duì)其執(zhí)行所有必需的操作。
(可選)從最終結(jié)果創(chuàng)建一個(gè) DataFrame。
我嘗試了method1b的Numpy版本:
def method3(): a = df.values arr = a[a[:,0] != 1]
但執(zhí)行時(shí)間要長(zhǎng)約40%。
原因可能是Numpy數(shù)組具有相同類(lèi)型的所有元素,因此array_condition列被強(qiáng)制浮動(dòng),然后創(chuàng)建整個(gè)Numpy數(shù)組,這需要一些時(shí)間。
第 2 部分:Numpy 和 Numba
要考慮的替代方法是使用Numba包 - 一種即時(shí) Python 編譯器。
我做了這樣的測(cè)試:
創(chuàng)建了一個(gè)Numpy數(shù)組(作為初步步驟):
a = df.values
原因是 JIT 編譯的方法能夠使用Numpy方法和類(lèi)型,但不能使用Pandas的方法和類(lèi)型。
為了執(zhí)行測(cè)試,我使用了與上面幾乎相同的方法,但使用了@njit注釋?zhuān)ㄐ枰?em>來(lái)自 numba import njit):
@njit def method4(): arr = a[a[:,0] != 1]
這次:
執(zhí)行時(shí)間約為method1b時(shí)間的 45% 。
但由于
a = df.values
已經(jīng)在測(cè)試循環(huán)之前執(zhí)行過(guò),因此這個(gè)結(jié)果是否與之前的測(cè)試有可比性存在疑問(wèn)。
無(wú)論如何,自己嘗試Numba,也許這對(duì)您來(lái)說(shuō)是一個(gè)有趣的選擇。

TA貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超6個(gè)贊
您可能會(huì)發(fā)現(xiàn)在這里使用numpy.where很有用。它將布爾掩碼轉(zhuǎn)換為數(shù)組索引,使生活更便宜。將其與 numpy.vstack 結(jié)合可以實(shí)現(xiàn)一些內(nèi)存便宜的操作:
def method3():
wh = np.where(array_condition == 1)
return np.vstack(tuple(col[wh] for col in (array1, array2, array3)))
這給出了以下時(shí)間:
>>> %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)
元組解包允許該操作在內(nèi)存上相當(dāng)輕,因?yàn)楫?dāng)對(duì)象被 vstack-ed 重新組合在一起時(shí),它會(huì)更小。如果您需要直接從 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 中按名稱(chēng)獲取列,然后在運(yùn)行中對(duì)這些列進(jìn)行元組解包。速度差不多:
>>> %timeit method3b()
96.6 ms ± 3.09 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
添加回答
舉報(bào)