Python 如何在pyspark中进行均值(目标)编码

Python 如何在pyspark中进行均值(目标)编码,python,encoding,pyspark,feature-extraction,Python,Encoding,Pyspark,Feature Extraction,我需要对数据集中的所有分类列进行平均(目标)编码。为了简化这个问题,假设我的数据集中有两列,第一列是标签列,第二列是分类列 e、 g 因此,根据平均编码策略: 输出应该是 label | cate1 0 | 0.5 1 | 0.5 0 | 0.0 0 | 0.0 1 | 1.0 我尝试过考拉来解决这个问题,但失败了。这就是我尝试过的: for col_name in convert_cols:

我需要对数据集中的所有分类列进行平均(目标)编码。为了简化这个问题,假设我的数据集中有两列,第一列是标签列,第二列是分类列

e、 g

因此,根据平均编码策略:

输出应该是

label | cate1    
  0   |  0.5   
  1   |  0.5    
  0   |  0.0    
  0   |  0.0    
  1   |  1.0
我尝试过考拉来解决这个问题,但失败了。这就是我尝试过的:

for col_name in convert_cols:


    cat_mean_dict = dict()
    # get category name <-> count dictionary
    cur_col_cate_count_ = ks_df[col_name].value_counts().to_dict()
    print(cur_col_cate_count_)

    # calculate all different categories positive result count and mean value
    start_time = time.time()
    for key in cur_col_cate_count_:

        current_col_positive_count = ks_df.loc[(ks_df['0'] == 1) & (ks_df[col_name] == key)].shape[0]
        key_mean = current_col_positive_count / cur_col_cate_count_[key]
        cat_mean_dict[key] = key_mean


    for i in range(ks_df.shape[0]):
        cate_origin_hash = ks_df.at[i, col_name]
        if cate_origin_hash in cat_mean_dict:
            ks_df.at[i, col_name] = cat_mean_dict[cate_origin_hash]
        else:
            ks_df.at[i, col_name] = -1

转换列中列名称的
:
cat_mean_dict=dict()
#获取类别名称计数字典
cur_col_cate_count_uuu=ks_df[col_name]。value_counts()。to_dict()
打印(当前颜色种类计数)
#计算所有不同类别的阳性结果计数和平均值
开始时间=time.time()
对于输入电流、颜色、计数:
当前列正计数=ks_df.loc[(ks_df['0']==1)和(ks_df[col_name]==key)]。形状[0]
键平均值=当前列正计数/当前列计数[键]
cat_mean_dict[key]=key_mean
对于范围内的i(ks_df.shape[0]):
cate_origin_hash=ks_df.at[i,col_name]
如果类别中的类别来源散列表示:
ks_df.at[i,col_name]=cat_mean_dict[cate_origin_hash]
其他:
ks_df.at[i,col_name]=-1
但是考拉不允许单元格级别的更新,这意味着我不能通过
ks_df.at[I,col_name]=new_值来修改值


因此,我希望有一些pyspark解决方案可以解决这个问题。

请在下面找到pyspark解决方案:

#火花输入
spark_数据=[行(标签=0,类别1='abc'),
行(标签=1,类别1='abc'),
行(label=0,cate1='def'),
行(label=0,cate1='def'),
行(标签=1,类别1='ghi')]
df=spark.createDataFrame(spark\u数据)
df.show()
>>>
+-----+-----+
|类别1 |标签|
+-----+-----+
|abc | 0|
|abc | 1|
|def | 0|
|def | 0|
|ghi | 1|
+-----+-----+
#作用
def target_mean_编码(df、col、target):
"""
:param df:pyspark.sql.dataframe
应用目标平均编码的数据帧
:param col:str列表
要应用目标编码的列列表
:param目标:str
目标列
:返回:
具有目标编码列的数据帧
"""
目标\u编码的\u列\u列表=[]
对于col中的c:
means=df.groupby(F.col(c)).agg(F.mean(target).别名(F“{c}u-mean_-encoding”))
dict=表示.toPandas()到dict()
目标_编码的_列=[F.when(F.col(c)=v,编码器)
对于v,zip中的编码器(dict_uC].values(),
dict_f[f{c}_mean_encoding”].values())]
target_encoded_columns_list.append(F.coalesce(*target_encoded_columns).alias(F“{c}u mean_encodeding”))
返回df.select(目标,*目标\u编码的\u列\u列表)
#功能适用于火花输入
df_target_encoded=target_mean_encodeding(df,col=['cate1'],target='label')
df_target_encoded.show()
>>> 
+-----+-------------------+
|标签|类别1_平均值|编码|
+-----+-------------------+
|    0|                0.5|
|    1|                0.5|
|    0|                0.0|
|    0|                0.0|
|    1|                1.0|
+-----+-------------------+
#如果要在目标后保留相同的列名,则
df_target_encoded.withColumnRename('cate1_mean_encodeding','cate1')
df_target_encoded.show()
>>>
+-----+-----+
|标签|类别1|
+-----+-----+
|    0|  0.5|
|    1|  0.5|
|    0|  0.0|
|    0|  0.0|
|    1|  1.0|
+-----+-----+

感谢代码Florian,您是否有建议如何实现K倍平均目标编码,如图所示:这是一个很好的答案。它使用pyspark(不做像将整个df转储到pandas中这样愚蠢的事情),并获得正确的编码@Alain ux应相应地奖励互联网积分。
for col_name in convert_cols:


    cat_mean_dict = dict()
    # get category name <-> count dictionary
    cur_col_cate_count_ = ks_df[col_name].value_counts().to_dict()
    print(cur_col_cate_count_)

    # calculate all different categories positive result count and mean value
    start_time = time.time()
    for key in cur_col_cate_count_:

        current_col_positive_count = ks_df.loc[(ks_df['0'] == 1) & (ks_df[col_name] == key)].shape[0]
        key_mean = current_col_positive_count / cur_col_cate_count_[key]
        cat_mean_dict[key] = key_mean


    for i in range(ks_df.shape[0]):
        cate_origin_hash = ks_df.at[i, col_name]
        if cate_origin_hash in cat_mean_dict:
            ks_df.at[i, col_name] = cat_mean_dict[cate_origin_hash]
        else:
            ks_df.at[i, col_name] = -1