Pyspark对一列中的不同值进行随机拆分(测试/训练),其中来自另一列的所有不同值都包含在每个拆分中

Pyspark对一列中的不同值进行随机拆分(测试/训练),其中来自另一列的所有不同值都包含在每个拆分中,pyspark,Pyspark,假设我有一个包含两列的数据框(id1和id2)。比如: df=sc.parallelize([(1,10),(1,11),(1,12),(1,13),(2,10),(2,11),(3,11),(3,13),(4,10),(4,11),(5,12),(6,12),(7,13),(8,13),(9,13),(10,13)]。toDF([“id1”,“id2”]) 我如何在id1上测试、训练分割此df(确保所有不同的id1值都在测试或训练分割中,而不是两者中),同时确保每个id2在测试和训练分割中至少

假设我有一个包含两列的数据框(
id1
id2
)。比如:

df=sc.parallelize([(1,10),(1,11),(1,12),(1,13),(2,10),(2,11),(3,11),(3,13),(4,10),(4,11),(5,12),(6,12),(7,13),(8,13),(9,13),(10,13)]。toDF([“id1”,“id2”])

我如何在
id1
上测试、训练分割此df(确保所有不同的
id1
值都在测试或训练分割中,而不是两者中),同时确保每个
id2
在测试和训练分割中至少表示一次,最好分层

为清楚起见,考虑到上述
df
,该分割将防止所有三个
id1
值1、2和4都存在,例如在
序列
分割中,因为
id2
10不会在
测试
分割中表示

例如,如果我使用
train,test=df.select('id1').randomspilt([80.20])
我不能保证
train
test
都会考虑所有
id2

如果我把它转过来,使用
sampleBy
来确保
train
test
中都有
id2
值,我将在
train
test
中得到不同的
id1

实际上,我使用的是更大的数据集~我的df中有200K行,具有~100K个不同的
id1
和~500个不同的
id2
。因此,测试、列车拆分将导致
测试中~80K个不同的
id1
列车中~20K个不同的
id1
测试和
列车都至少有一个
id2
示例,最好分层

此代码将生成一个示例,说明此问题的较大数据集可能是什么样子的,尽管在
id2
上使用了强制倾斜:

def rand_id(x):
    id2 = np.arange(1,501,1)
    prob = [0.10]*40+[1.0]*450+[5]*8+[20]*2
    prob /= np.sum(prob)
    np.random.choice(id2, 1, p=prob)
    return (np.random.randint(1, 100000), int(np.random.choice(id2, 1, p=prob)))
    
df = sc.parallelize([(0,0)] * 200000).map(rand_id).toDF(["id1","id2"])

我发现了一些围绕这一主题的问题,但没有一个与我对这两列的约束相结合。

在这个问题中,你有两条规则-1。
id1的相同值必须在测试或序列2中。列车和测试集中必须至少有一个相同的
id2
值。如果发生冲突,您可以指定规则的优先级吗。例如,如果df是
(1,10)、(2,11)、(1,10)
,您希望如何分割它?我提供的示例
df
I防止了这种冲突,因为至少有两个不同的
id1
值在一行中具有每个不同的
id2
值。对于我的个人用例,我将删除给定的
id2
没有至少两个不同的
id1
值关联的所有行。在这个问题中,您有两条规则-1。
id1的相同值必须在测试或序列2中。列车和测试集中必须至少有一个相同的
id2
值。如果发生冲突,您可以指定规则的优先级吗。例如,如果df是
(1,10)、(2,11)、(1,10)
,您希望如何分割它?我提供的示例
df
I防止了这种冲突,因为至少有两个不同的
id1
值在一行中具有每个不同的
id2
值。对于我的个人用例,我将删除给定的
id2
没有至少两个不同的
id1
值关联的所有行。