亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

搜索

Pandas大數(shù)據(jù)集分組抽樣:靈活控制每組樣本量與替換行為

DDD
發(fā)布: 2025-10-16 14:31:01
原創(chuàng)
278人瀏覽過(guò)

Pandas大數(shù)據(jù)集分組抽樣:靈活控制每組樣本量與替換行為

本文詳細(xì)介紹了如何在pandas中對(duì)大型數(shù)據(jù)集進(jìn)行高效的分組抽樣,特別是當(dāng)每個(gè)分組需要不同數(shù)量的樣本,并且需要根據(jù)分組大小動(dòng)態(tài)調(diào)整是否允許重復(fù)抽樣(`replace`參數(shù))時(shí)。通過(guò)構(gòu)建一個(gè)自定義函數(shù)并結(jié)合`groupby().apply()`方法,可以實(shí)現(xiàn)比傳統(tǒng)循環(huán)更優(yōu)的性能和更靈活的控制,確保抽樣邏輯的準(zhǔn)確性和效率。

在數(shù)據(jù)分析和機(jī)器學(xué)習(xí)任務(wù)中,我們經(jīng)常需要從數(shù)據(jù)集中抽取樣本。當(dāng)數(shù)據(jù)集非常龐大,并且需要根據(jù)某個(gè)或多個(gè)列進(jìn)行分組,然后對(duì)每個(gè)分組執(zhí)行抽樣時(shí),情況會(huì)變得復(fù)雜。更進(jìn)一步,如果每個(gè)分組所需的樣本數(shù)量不同,并且需要根據(jù)分組的實(shí)際大小動(dòng)態(tài)決定是否允許重復(fù)抽樣,那么傳統(tǒng)的groupby().sample()方法就顯得力不從心。

問(wèn)題背景:傳統(tǒng)方法的局限性

Pandas提供了DataFrame.groupby().sample(n=...)方法,可以方便地對(duì)每個(gè)分組抽取固定數(shù)量的樣本。例如:

df.groupby("a").sample(n=1, random_state=1)
登錄后復(fù)制

然而,這個(gè)方法無(wú)法直接處理每個(gè)分組需要不同n值的情況。一種常見(jiàn)的、但效率低下的做法是遍歷每個(gè)分組,然后單獨(dú)進(jìn)行過(guò)濾和抽樣:

# 假設(shè) 'm_values' 是一個(gè)字典或列表,包含每個(gè)組 'a' 對(duì)應(yīng)的樣本數(shù)量
for group_val, m in m_values.items():
    filter_df = df.loc[(df['a'] == group_val)]
    # ... 進(jìn)行抽樣,并根據(jù)條件設(shè)置 replace 參數(shù)
    # ... 最后將結(jié)果合并
登錄后復(fù)制

這種基于循環(huán)的方法在處理?yè)碛写罅课ㄒ环纸M(例如10萬(wàn)個(gè))的大型數(shù)據(jù)集(例如9000萬(wàn)行)時(shí),會(huì)因?yàn)轭l繁的數(shù)據(jù)過(guò)濾、創(chuàng)建子DataFrame以及最終的合并操作而導(dǎo)致性能瓶頸

此外,關(guān)于replace參數(shù)的動(dòng)態(tài)設(shè)置也是一個(gè)關(guān)鍵點(diǎn):

  • 如果分組的記錄數(shù)小于所需樣本數(shù)n,為了達(dá)到n個(gè)樣本,必須允許重復(fù)抽樣(replace=True)。
  • 如果分組的記錄數(shù)大于或等于所需樣本數(shù)n,通常我們希望抽取n個(gè)唯一的樣本(replace=False)。

高效解決方案:結(jié)合 groupby().apply() 和自定義函數(shù)

Pandas的groupby().apply()方法允許我們將一個(gè)自定義函數(shù)應(yīng)用到每個(gè)分組上,從而實(shí)現(xiàn)復(fù)雜的、組級(jí)別的數(shù)據(jù)操作。這是解決上述問(wèn)題的理想方案,因?yàn)樗軐ython循環(huán)的邏輯“推”到C層面執(zhí)行,從而獲得更好的性能。

1. 準(zhǔn)備樣本數(shù)量映射

首先,我們需要一個(gè)機(jī)制來(lái)告訴每個(gè)分組應(yīng)該抽取多少樣本。這通??梢酝ㄟ^(guò)一個(gè)包含分組鍵和對(duì)應(yīng)樣本數(shù)量的DataFrame來(lái)構(gòu)建,并將其轉(zhuǎn)換為字典,以便快速查找。

假設(shè)我們有一個(gè)DataFrame df1,其中包含每個(gè)組a所需的樣本數(shù)量:

壁紙樣機(jī)神器
壁紙樣機(jī)神器

免費(fèi)壁紙樣機(jī)生成

壁紙樣機(jī)神器0
查看詳情 壁紙樣機(jī)神器
import pandas as pd

# df1: 定義每個(gè)組 'a' 對(duì)應(yīng)的樣本數(shù)量
df1 = pd.DataFrame({
    'a': [1, 2, 3],
    'count': [1, 3, 2]
})

# 將 df1 轉(zhuǎn)換為字典,方便查找
sample_counts_map = df1.set_index("a")["count"].to_dict()
# sample_counts_map -> {1: 1, 2: 3, 3: 2}
登錄后復(fù)制

2. 定義自定義抽樣函數(shù)

接下來(lái),我們創(chuàng)建一個(gè)函數(shù),該函數(shù)將作為apply()的參數(shù),對(duì)每個(gè)分組DataFrame進(jìn)行操作。這個(gè)函數(shù)需要接收分組DataFrame、樣本數(shù)量映射字典以及隨機(jī)種子作為參數(shù)。

def get_sample(group_df, sample_counts_dict, random_state):
    """
    對(duì)每個(gè)分組DataFrame進(jìn)行抽樣。
    根據(jù)分組鍵從 sample_counts_dict 獲取所需的樣本數(shù)量,
    并根據(jù)分組大小動(dòng)態(tài)調(diào)整 replace 參數(shù)。

    Args:
        group_df (pd.DataFrame): 當(dāng)前分組的DataFrame。
        sample_counts_dict (dict): 包含每個(gè)組 'a' 對(duì)應(yīng)樣本數(shù)量的字典。
        random_state (int): 隨機(jī)種子,用于保證抽樣結(jié)果的可復(fù)現(xiàn)性。

    Returns:
        pd.DataFrame: 抽樣后的DataFrame,如果該組不需要抽樣則返回 None。
    """
    # 獲取當(dāng)前分組的鍵值 (例如 'a' 列的值)
    group_key = group_df["a"].iat[0] # iat[0] 效率更高,因?yàn)槲覀冎澜M內(nèi) 'a' 值都相同

    # 從映射字典中獲取該組所需的樣本數(shù)量
    n_samples = sample_counts_dict.get(group_key)

    # 如果該組的鍵不在映射字典中,或者 n_samples 為 None,則不進(jìn)行抽樣
    if n_samples is None:
        return None

    # 動(dòng)態(tài)設(shè)置 replace 參數(shù)
    # 如果分組的實(shí)際記錄數(shù)小于或等于所需樣本數(shù) n_samples,則必須允許重復(fù)抽樣 (replace=True)
    # 否則,如果分組記錄數(shù)大于 n_samples,則不允許重復(fù)抽樣 (replace=False)
    allow_replace = len(group_df) <= n_samples

    # 執(zhí)行抽樣
    return group_df.sample(n=n_samples, random_state=random_state, replace=allow_replace)
登錄后復(fù)制

3. 應(yīng)用 groupby().apply()

最后,我們將這個(gè)自定義函數(shù)應(yīng)用到原始DataFrame的groupby對(duì)象上。

# df2: 原始數(shù)據(jù),待抽樣
df2 = pd.DataFrame({
    'a': [1, 1, 1, 2, 2, 3, 3],
    'x': ['a', 'b', 'c', 'd', 'e', 'f', 'g']
})

# 使用 groupby().apply() 進(jìn)行抽樣
# group_keys=False 可以避免在結(jié)果中添加分組鍵作為索引,提高性能
sampled_df = df2.groupby("a", group_keys=False).apply(
    get_sample,
    sample_counts_dict=sample_counts_map,
    random_state=6
)

print(sampled_df)
登錄后復(fù)制

輸出結(jié)果:

   a  x
0  1  a
3  2  d
4  2  e
4  2  e
5  3  f
6  3  g
登錄后復(fù)制

從結(jié)果可以看出:

  • 組 a=1:原始有3條記錄,需要1條樣本,結(jié)果是1條(replace=False)。
  • 組 a=2:原始有2條記錄,需要3條樣本,結(jié)果是3條,其中一條是重復(fù)的(replace=True)。
  • 組 a=3:原始有2條記錄,需要2條樣本,結(jié)果是2條(replace=False)。

這完美地實(shí)現(xiàn)了我們動(dòng)態(tài)抽樣的需求。

關(guān)鍵點(diǎn)與注意事項(xiàng)

  1. group_keys=False: 在groupby().apply()中設(shè)置group_keys=False是一個(gè)重要的性能優(yōu)化。它阻止了apply操作在結(jié)果DataFrame中將分組鍵作為額外的索引層,這在處理大量分組時(shí)可以顯著減少內(nèi)存開(kāi)銷(xiāo)和處理時(shí)間。
  2. random_state: 設(shè)置random_state參數(shù)可以確保每次運(yùn)行代碼時(shí),抽樣結(jié)果都是一致的,這對(duì)于調(diào)試和結(jié)果復(fù)現(xiàn)至關(guān)重要。
  3. sample_counts_dict 的效率: 將樣本數(shù)量映射預(yù)先構(gòu)建成字典,使得在自定義函數(shù)中通過(guò)dict.get()查找樣本數(shù)量的操作非常高效,是O(1)的平均時(shí)間復(fù)雜度。
  4. len(group_df) <= n_samples 邏輯: 理解這個(gè)條件對(duì)于正確實(shí)現(xiàn)動(dòng)態(tài)replace行為至關(guān)重要。當(dāng)分組的記錄數(shù)不足以提供所需樣本數(shù)時(shí),必須允許重復(fù)抽樣;否則,為了獲取唯一樣本,應(yīng)禁止重復(fù)抽樣。
  5. 內(nèi)存管理: 盡管apply()比顯式循環(huán)更高效,但對(duì)于極大的分組,group_df本身可能仍然占用大量?jī)?nèi)存。在處理數(shù)億甚至數(shù)十億行的數(shù)據(jù)集時(shí),可能需要考慮使用更高級(jí)的分布式計(jì)算框架(如PySpark、Dask)來(lái)避免單機(jī)內(nèi)存限制。

總結(jié)

通過(guò)利用Pandas的groupby().apply()方法結(jié)合一個(gè)精心設(shè)計(jì)的自定義抽樣函數(shù),我們可以高效地解決大型數(shù)據(jù)集上復(fù)雜的分組抽樣問(wèn)題。這種方法不僅能夠靈活地為每個(gè)分組指定不同的樣本數(shù)量,還能根據(jù)分組的實(shí)際大小智能地調(diào)整是否允許重復(fù)抽樣,從而在保證數(shù)據(jù)質(zhì)量的同時(shí),顯著提升處理效率。

以上就是Pandas大數(shù)據(jù)集分組抽樣:靈活控制每組樣本量與替換行為的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!

最佳 Windows 性能的頂級(jí)免費(fèi)優(yōu)化軟件
最佳 Windows 性能的頂級(jí)免費(fèi)優(yōu)化軟件

每個(gè)人都需要一臺(tái)速度更快、更穩(wěn)定的 PC。隨著時(shí)間的推移,垃圾文件、舊注冊(cè)表數(shù)據(jù)和不必要的后臺(tái)進(jìn)程會(huì)占用資源并降低性能。幸運(yùn)的是,許多工具可以讓 Windows 保持平穩(wěn)運(yùn)行。

下載
來(lái)源:php中文網(wǎng)
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn
最新問(wèn)題
開(kāi)源免費(fèi)商場(chǎng)系統(tǒng)廣告
最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板
關(guān)于我們 免責(zé)申明 意見(jiàn)反饋 講師合作 廣告合作 最新更新
php中文網(wǎng):公益在線php培訓(xùn),幫助PHP學(xué)習(xí)者快速成長(zhǎng)!
關(guān)注服務(wù)號(hào) 技術(shù)交流群
PHP中文網(wǎng)訂閱號(hào)
每天精選資源文章推送
PHP中文網(wǎng)APP
隨時(shí)隨地碎片化學(xué)習(xí)
PHP中文網(wǎng)抖音號(hào)
發(fā)現(xiàn)有趣的

Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號(hào)