簡體   English   中英

如何從 PySpark DataFrame 中隨機抽取一行?

[英]How take a random row from a PySpark DataFrame?

如何從 PySpark DataFrame 中獲取隨機行? 我只看到以分數作為參數的方法sample() 將此分數設置為1/numberOfRows會導致隨機結果,有時我不會得到任何行。

RDD有一個方法takeSample()將您希望樣本包含的元素數量作為參數。 我知道這可能很慢,因為您必須計算每個分區,但是有沒有辦法在 DataFrame 上獲得這樣的東西?

您可以簡單地在RDD上調用takeSample

df = sqlContext.createDataFrame(
    [(1, "a"), (2, "b"), (3, "c"), (4, "d")], ("k", "v"))
df.rdd.takeSample(False, 1, seed=0)
## [Row(k=3, v='c')]

如果您不想收集,您可以簡單地采用更高的分數和限制:

df.sample(False, 0.1, seed=0).limit(1)

不同類型的樣品

隨機抽樣 % 有替換和無替換的數據

import pyspark.sql.functions as F
#Randomly sample 50% of the data without replacement
sample1 = df.sample(False, 0.5, seed=0)

#Randomly sample 50% of the data with replacement
sample1 = df.sample(True, 0.5, seed=0)

#Take another sample exlcuding records from previous sample using Anti Join
sample2 = df.join(sample1, on='ID', how='left_anti').sample(False, 0.5, seed=0)

#Take another sample exlcuding records from previous sample using Where
sample1_ids = [row['ID'] for row in sample1.ID]
sample2 = df.where(~F.col('ID').isin(sample1_ids)).sample(False, 0.5, seed=0)

#Generate a startfied sample of the data across column(s)
#Sampling is probabilistic and thus cannot guarantee an exact number of rows
fractions = {
        'NJ': 0.5, #Take about 50% of records where state = NJ
    'NY': 0.25, #Take about 25% of records where state = NY
    'VA': 0.1, #Take about 10% of records where state = VA
}
stratified_sample = df.sampleBy(F.col('state'), fractions, seed=0)

這是使用 Pandas DataFrame.Sample方法的替代方法。 這使用 spark applyInPandas方法來分發組,可從 Spark 3.0.0 獲得。 這允許您為每組選擇確切數量的行。

我已將argskwargs添加到函數中,以便您可以訪問DataFrame.Sample的其他參數。

def sample_n_per_group(n, *args, **kwargs):
    def sample_per_group(pdf):
        return pdf.sample(n, *args, **kwargs)
    return sample_per_group

df = spark.createDataFrame(
    [
        (1, 1.0), 
        (1, 2.0), 
        (2, 3.0), 
        (2, 5.0), 
        (2, 10.0)
    ],
    ("id", "v")
)

(df.groupBy("id")
   .applyInPandas(
        sample_n_per_group(1, random_state=2), 
        schema=df.schema
   )
)

要了解非常大的團體的限制,請參閱文檔

此功能需要完全洗牌。 一個組的所有數據都會被加載到內存中,因此用戶應該意識到如果數據傾斜並且某些組太大而無法放入內存,則用戶應該意識到潛在的OOM風險。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM