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

搜索

Pandas中基于組的靈活采樣:實(shí)現(xiàn)不同n值與動(dòng)態(tài)替換策略

碧海醫(yī)心
發(fā)布: 2025-10-16 10:28:23
原創(chuàng)
320人瀏覽過

Pandas中基于組的靈活采樣:實(shí)現(xiàn)不同n值與動(dòng)態(tài)替換策略

本文深入探討了在pandas中對(duì)大型數(shù)據(jù)集進(jìn)行分組采樣的高效方法。針對(duì)傳統(tǒng)`groupby().sample()`無法滿足各組不同采樣數(shù)量`n`以及動(dòng)態(tài)替換策略(`replace=true/false`)的需求,我們提出并詳細(xì)解釋了如何利用`groupby().apply()`結(jié)合自定義函數(shù)來實(shí)現(xiàn)這一復(fù)雜采樣邏輯,顯著提升了處理效率和代碼可讀性,適用于大規(guī)模數(shù)據(jù)場(chǎng)景。

Pandas分組采樣:實(shí)現(xiàn)動(dòng)態(tài)n值與替換策略

在數(shù)據(jù)分析中,我們經(jīng)常需要對(duì)數(shù)據(jù)集進(jìn)行分組(groupby)操作,并從每個(gè)組中抽取一定數(shù)量的樣本。然而,當(dāng)每個(gè)組所需的樣本數(shù)量n不同,并且采樣是否需要替換(replace)也依賴于組的原始大小時(shí),標(biāo)準(zhǔn)的df.groupby("col").sample(n=...)方法就顯得力不從心了。對(duì)于大型數(shù)據(jù)集,簡(jiǎn)單的循環(huán)遍歷和過濾操作會(huì)導(dǎo)致性能瓶頸。本教程將介紹一種高效且靈活的解決方案,利用groupby().apply()結(jié)合自定義函數(shù)來解決這一挑戰(zhàn)。

挑戰(zhàn):動(dòng)態(tài)采樣數(shù)量與替換策略

假設(shè)我們有一個(gè)包含數(shù)千萬甚至上億條記錄的大型數(shù)據(jù)集df_main,其中包含一個(gè)分組列a(具有大量唯一值,例如10萬個(gè))。我們還有一個(gè)輔助數(shù)據(jù)集df_sample_counts,它指定了列a中每個(gè)唯一值應(yīng)該采樣多少條記錄。此外,采樣規(guī)則要求:

  1. 如果組的原始記錄數(shù)小于或等于所需的采樣數(shù)n,則使用replace=True進(jìn)行采樣,以確保能達(dá)到指定的n(允許重復(fù))。
  2. 如果組的原始記錄數(shù)大于所需的采樣數(shù)n,則使用replace=False進(jìn)行采樣,以獲取盡可能多的唯一記錄。

傳統(tǒng)的df.groupby("a").sample(n=1)只能對(duì)所有組應(yīng)用相同的n值。而通過循環(huán)遍歷每個(gè)組并單獨(dú)采樣,雖然能實(shí)現(xiàn)功能,但在處理大數(shù)據(jù)集時(shí)效率低下,無法滿足生產(chǎn)環(huán)境的需求。

解決方案:groupby().apply()與自定義函數(shù)

Pandas的groupby().apply()方法為執(zhí)行復(fù)雜的組級(jí)操作提供了強(qiáng)大的靈活性。我們可以定義一個(gè)自定義函數(shù),該函數(shù)將接收每個(gè)分組的DataFrame作為輸入,并在其中實(shí)現(xiàn)動(dòng)態(tài)采樣邏輯。

1. 準(zhǔn)備數(shù)據(jù)

首先,我們創(chuàng)建兩個(gè)示例DataFrame,模擬原始數(shù)據(jù)和采樣數(shù)量配置。

import pandas as pd
import numpy as np

# 模擬采樣數(shù)量配置 DataFrame (df1)
data_counts = {'a': [1, 2, 3], 'count': [1, 3, 2]}
df1 = pd.DataFrame(data_counts)
print("df1 (采樣數(shù)量配置):")
print(df1)

print("-" * 30)

# 模擬原始數(shù)據(jù) DataFrame (df2)
data_original = {'a': [1, 1, 1, 2, 2, 3, 3], 'x': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}
df2 = pd.DataFrame(data_original)
print("df2 (原始數(shù)據(jù)):")
print(df2)
登錄后復(fù)制

輸出示例:

硅基智能
硅基智能

基于Web3.0的元宇宙,去中心化的互聯(lián)網(wǎng),高質(zhì)量、沉浸式元宇宙直播平臺(tái),用數(shù)字化重新定義直播

硅基智能62
查看詳情 硅基智能
df1 (采樣數(shù)量配置):
   a  count
0  1      1
1  2      3
2  3      2
------------------------------
df2 (原始數(shù)據(jù)):
   a  x
0  1  a
1  1  b
2  1  c
3  2  d
4  2  e
5  3  f
6  3  g
登錄后復(fù)制

2. 構(gòu)建采樣數(shù)量查找字典

為了在自定義函數(shù)中高效地獲取每個(gè)組的采樣數(shù)量n,我們將df1轉(zhuǎn)換為一個(gè)字典,其中鍵是分組列a的值,值是對(duì)應(yīng)的采樣數(shù)量count。

sample_counts_dict = df1.set_index("a")["count"].to_dict()
print("\n采樣數(shù)量查找字典:")
print(sample_counts_dict)
登錄后復(fù)制

輸出示例:

采樣數(shù)量查找字典:
{1: 1, 2: 3, 3: 2}
登錄后復(fù)制

3. 定義自定義采樣函數(shù)

這個(gè)函數(shù)將是解決方案的核心。它接收一個(gè)分組的DataFrame (df_group),查找字典 (dct) 和一個(gè)隨機(jī)種子 (random_state)。

def get_sample(df_group, dct, random_state):
    # 獲取當(dāng)前組的分組鍵 'a' 的值
    # df_group["a"].iat[0] 比 df_group["a"].iloc[0] 更快,因?yàn)樗苯釉L問底層數(shù)組
    group_key = df_group["a"].iat[0]

    # 從字典中獲取當(dāng)前組的采樣數(shù)量 n
    n_samples = dct.get(group_key)

    # 如果字典中沒有對(duì)應(yīng)的采樣數(shù)量,則不進(jìn)行采樣,返回None
    if n_samples is None:
        return None # 或返回一個(gè)空的DataFrame,取決于具體需求

    # 根據(jù)組的實(shí)際大小和所需的采樣數(shù)量 n_samples 決定 replace 參數(shù)
    # 如果組的大小小于或等于 n_samples,則允許替換 (replace=True)
    # 否則,不允許替換 (replace=False)
    replace_flag = len(df_group) <= n_samples

    # 執(zhí)行采樣操作
    return df_group.sample(n=n_samples, random_state=random_state, replace=replace_flag)
登錄后復(fù)制

函數(shù)邏輯詳解:

  • group_key = df_group["a"].iat[0]: 在apply操作中,df_group是原始DataFrame中屬于某個(gè)特定組的所有行。iat[0]用于高效地獲取該組的第一個(gè)(也是唯一的)a值,即當(dāng)前組的標(biāo)識(shí)。
  • n_samples = dct.get(group_key): 使用get()方法從預(yù)先構(gòu)建的sample_counts_dict中安全地獲取當(dāng)前組所需的采樣數(shù)量。如果group_key不存在于字典中,get()會(huì)返回None。
  • if n_samples is None: return None: 處理df2中存在但df1中未指定采樣數(shù)量的組。在這種情況下,我們選擇不返回任何樣本。
  • replace_flag = len(df_group) <= n_samples: 這是實(shí)現(xiàn)動(dòng)態(tài)替換策略的關(guān)鍵。如果當(dāng)前組的行數(shù)(len(df_group))小于或等于目標(biāo)采樣數(shù)n_samples,則replace設(shè)置為True,允許重復(fù)采樣以達(dá)到n_samples。否則,replace設(shè)置為False,確保所有樣本都是唯一的。
  • df_group.sample(...): 對(duì)當(dāng)前組的DataFrame執(zhí)行采樣操作,并傳入計(jì)算出的n_samples、random_state和replace_flag。

4. 應(yīng)用自定義函數(shù)進(jìn)行分組采樣

現(xiàn)在,我們將自定義函數(shù)get_sample應(yīng)用到df2的groupby("a")結(jié)果上。

# 使用 groupby().apply() 進(jìn)行分組采樣
# group_keys=False 可以避免在結(jié)果中添加分組鍵作為額外的索引層,提高效率
sampled_df = df2.groupby("a", group_keys=False).apply(
    get_sample,
    dct=sample_counts_dict,
    random_state=6 # 保持隨機(jī)性可復(fù)現(xiàn)
)

print("\n最終采樣結(jié)果:")
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é)果可以看出:

  • 對(duì)于a=1,df1要求采樣1個(gè),df2有3個(gè),所以采樣1個(gè)(replace=False)。
  • 對(duì)于a=2,df1要求采樣3個(gè),df2有2個(gè),所以采樣3個(gè)(replace=True,導(dǎo)致e重復(fù))。
  • 對(duì)于a=3,df1要求采樣2個(gè),df2有2個(gè),所以采樣2個(gè)(replace=True或False都可以,此處len(df_group) <= n_samples為真,所以是True,但實(shí)際效果是取全部不重復(fù))。

注意事項(xiàng)與性能考量

  1. group_keys=False: 在groupby().apply()中設(shè)置group_keys=False是一個(gè)良好的實(shí)踐,尤其是在你不需要分組鍵作為最終DataFrame索引的一部分時(shí)。它可以減少Pandas在內(nèi)部處理索引的開銷,從而提高性能。
  2. random_state: 使用random_state參數(shù)可以確保你的采樣結(jié)果是可復(fù)現(xiàn)的。在調(diào)試或需要一致結(jié)果時(shí),這是一個(gè)非常重要的參數(shù)。
  3. apply()的性能: 盡管apply()比顯式Python循環(huán)更高效,但它仍然在Python層面對(duì)每個(gè)組執(zhí)行操作。對(duì)于極端龐大的數(shù)據(jù)集和復(fù)雜的操作,如果能找到完全向量化的Pandas或NumPy函數(shù)替代,性能會(huì)更好。然而,對(duì)于這種需要?jiǎng)討B(tài)邏輯(如條件判斷replace參數(shù))的場(chǎng)景,apply()通常是最佳的折衷方案。
  4. 內(nèi)存使用: 對(duì)于非常大的數(shù)據(jù)集,如果每個(gè)組都很大,apply()可能會(huì)在內(nèi)存中加載整個(gè)組。請(qǐng)確保你的系統(tǒng)有足夠的內(nèi)存來處理。
  5. 處理缺失的組配置: dct.get(group_key)和隨后的if n_samples is None: return None有效地處理了原始數(shù)據(jù)中存在但df1中沒有指定采樣數(shù)量的組。你可以根據(jù)業(yè)務(wù)需求選擇返回空DataFrame或跳過這些組。

總結(jié)

通過結(jié)合使用Pandas的groupby().apply()方法和精心設(shè)計(jì)的自定義函數(shù),我們能夠優(yōu)雅且高效地解決在大型數(shù)據(jù)集中進(jìn)行復(fù)雜分組采樣的問題。這種方法不僅能夠靈活地處理每個(gè)組不同的采樣數(shù)量n,還能根據(jù)組的實(shí)際大小動(dòng)態(tài)調(diào)整采樣時(shí)的替換策略,從而滿足多樣化的數(shù)據(jù)分析需求,同時(shí)保持代碼的清晰性和可維護(hù)性。

以上就是Pandas中基于組的靈活采樣:實(shí)現(xiàn)不同n值與動(dòng)態(tài)替換策略的詳細(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)行。

下載
來源: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
最新問題
開源免費(fèi)商場(chǎng)系統(tǒng)廣告
最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板
關(guān)于我們 免責(zé)申明 意見反饋 講師合作 廣告合作 最新更新
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)