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

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

Pandas 向量化:計(jì)算每組滿足條件的分?jǐn)?shù)

Pandas 向量化:計(jì)算每組滿足條件的分?jǐn)?shù)

回首憶惘然 2021-09-11 16:08:38
假設(shè)我們有一張客戶及其支出表。import pandas as pddf = pd.DataFrame({    "Name":  ["Alice", "Bob", "Bob", "Charles"],    "Spend": [3, 5, 7, 9]})LIMIT = 6對(duì)于每個(gè)客戶,我們可以使用以下apply方法計(jì)算他的支出中大于 6 的部分:df.groupby("Name").apply(    lambda grp: len(grp[grp["Spend"] > LIMIT]) / len(grp))NameAlice      0.0Bob        0.5Charles    1.0然而,該apply方法只是一個(gè)循環(huán),如果有很多客戶,它會(huì)很慢。問(wèn)題:有沒有更快的方法,大概是使用矢量化?從 0.23.4 版本開始, SeriesGroupBy 不支持比較運(yùn)算符:(df.groupby("Name") ["Spend"] > LIMIT).mean()TypeError: '>' not supported between instances of 'SeriesGroupBy' and 'int'下面的代碼導(dǎo)致 Alice 的值為空:df[df["Spend"] > LIMIT].groupby("Name").size() / df.groupby("Name").size()NameAlice      NaNBob        0.5Charles    1.0下面的代碼給出了正確的結(jié)果,但它要求我們要么修改表格,要么制作副本以避免修改原始表格。df["Dummy"] = 1 * (df["Spend"] > LIMIT)df.groupby("Name") ["Dummy"] .sum() / df.groupby("Name").size()
查看完整描述

1 回答

?
白衣非少年

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

Groupby 不使用矢量化,但它具有使用 Cython 優(yōu)化的聚合函數(shù)。


你可以取平均值:


(df["Spend"] > LIMIT).groupby(df["Name"]).mean()


df["Spend"].gt(LIMIT).groupby(df["Name"]).mean()

或者用div0 替換 NaN:


df[df["Spend"] > LIMIT].groupby("Name").size() \

.div(df.groupby("Name").size(), fill_value = 0)


df["Spend"].gt(LIMIT).groupby(df["Name"]).sum() \

.div(df.groupby("Name").size(), fill_value = 0)

以上每個(gè)都會(huì)產(chǎn)生


Name

Alice      0.0

Bob        0.5

Charles    1.0

dtype: float64

表現(xiàn)

取決于每個(gè)條件過(guò)濾的行數(shù)和行數(shù),因此最好在真實(shí)數(shù)據(jù)上進(jìn)行測(cè)試。


np.random.seed(123)


N = 100000

df = pd.DataFrame({

    "Name":  np.random.randint(1000, size = N),

    "Spend": np.random.randint(10, size = N)

})

LIMIT = 6


In [10]: %timeit df["Spend"].gt(LIMIT).groupby(df["Name"]).mean()

6.16 ms ± 332 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)


In [11]: %timeit df[df["Spend"] > LIMIT].groupby("Name").size().div(df.groupby("Name").size(), fill_value = 0)

6.35 ms ± 95.1 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)


In [12]: %timeit df["Spend"].gt(LIMIT).groupby(df["Name"]).sum().div(df.groupby("Name").size(), fill_value = 0)

9.66 ms ± 365 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)


# RafaelC comment solution

In [13]: %timeit df.groupby("Name")["Spend"].apply(lambda s: (s > LIMIT).sum() / s.size)

400 ms ± 27.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)


In [14]: %timeit df.groupby("Name")["Spend"].apply(lambda s: (s > LIMIT).mean())

328 ms ± 6.12 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

這個(gè) NumPy 解決方案是矢量化的,但有點(diǎn)復(fù)雜:


In [15]: %%timeit

    ...: i, r = pd.factorize(df["Name"])

    ...: a = pd.Series(np.bincount(i), index = r)

    ...: 

    ...: i1, r1 = pd.factorize(df["Name"].values[df["Spend"].values > LIMIT])

    ...: b = pd.Series(np.bincount(i1), index = r1)

    ...: 

    ...: df1 = b.div(a, fill_value = 0)

    ...: 

5.05 ms ± 82.7 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)


查看完整回答
反對(duì) 回復(fù) 2021-09-11
  • 1 回答
  • 0 關(guān)注
  • 237 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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