第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

加速大型數(shù)組和數(shù)據(jù)集的操作(Pandas 慢,Numpy 更好,進(jìn)一步改進(jìn)?)

加速大型數(shù)組和數(shù)據(jù)集的操作(Pandas 慢,Numpy 更好,進(jìn)一步改進(jìn)?)

森林海 2022-06-14 15:34:45
我有一個(gè)包含數(shù)百萬(wàn)行和大約 6 列的大型數(shù)據(jù)集。數(shù)據(jù)當(dāng)前位于 Pandas 數(shù)據(jù)框中,我正在尋找對(duì)其進(jìn)行操作的最快方法。例如,假設(shè)我想刪除一列中值為“1”的所有行。這是我的最小工作示例:# Create dummy data arrays and pandas dataframearray_size = int(5e6)array1 = np.random.rand(array_size)array2 = np.random.rand(array_size)array3 = np.random.rand(array_size)array_condition = np.random.randint(0, 3, size=array_size)df = pd.DataFrame({'array_condition': array_condition, 'array1': array1, 'array2': array2, 'array3': array3})def method1():    df_new = df.drop(df[df.array_condition == 1].index)編輯:正如 Henry Yik 在評(píng)論中指出的,更快的 Pandas 方法是這樣的:def method1b():    df_new = df[df.array_condition != 1]我相信 Pandas 在這種事情上可能會(huì)很慢,所以我還使用 numpy 實(shí)現(xiàn)了一個(gè)方法,將每一列作為一個(gè)單獨(dú)的數(shù)組處理:def method2():    masking = array_condition != 1    array1_new = array1[masking]    array2_new = array2[masking]    array3_new = array3[masking]    array_condition_new = array_condition[masking]    結(jié)果:%timeit method1()625 ms ± 7.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)%timeit methodb()158 ms ± 7.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)%timeit method2()138 ms ± 3.8 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)因此,我們確實(shí)看到使用 numpy 的性能略有顯著提升。然而,這是以可讀性低得多的代碼為代價(jià)的(即必須創(chuàng)建一個(gè)掩碼并將其應(yīng)用于每個(gè)數(shù)組)。這種方法似乎不像我有 30 列數(shù)據(jù)那樣可擴(kuò)展,我需要很多代碼行來(lái)將掩碼應(yīng)用于每個(gè)數(shù)組!此外,允許可選列會(huì)很有用,因此此方法可能會(huì)在嘗試對(duì)空數(shù)組進(jìn)行操作時(shí)失敗。因此,我有兩個(gè)問(wèn)題:1)在numpy中是否有更清潔/更靈活的方法來(lái)實(shí)現(xiàn)這一點(diǎn)?2)或者更好,我可以在這里使用任何更高性能的方法嗎?例如 JIT(numba?)、Cython 還是其他?PS,在實(shí)踐中,可以使用就地操作,一旦數(shù)據(jù)被丟棄,就用新數(shù)組替換舊數(shù)組
查看完整描述

2 回答

?
慕的地8271018

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超4個(gè)贊

第 1 部分:Pandas 和(也許)Numpy

比較您的method1bmethod2

  • 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è)有趣的選擇。


查看完整回答
反對(duì) 回復(fù) 2022-06-14
?
慕妹3242003

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)


查看完整回答
反對(duì) 回復(fù) 2022-06-14
  • 2 回答
  • 0 關(guān)注
  • 135 瀏覽
慕課專(zhuān)欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢(xún)優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)