在给定参考表的情况下,我试图标准化我的DataFrames的标题名称。
我的参考表是一个DataFrame,其行中有变量,标准名称和所有可能的变体名称都作为列:
+-------------+---------+---------+
|Standard_name|Variant_1|Variant_2|
+-------------+---------+---------+
| Pressure| Press| Press_1|
| Speed| Speed_| Rate|
+-------------+---------+---------+
说我有一个带有这些列名的数据的DataFrame:
['Pressure', 'Rate', 'Altitude']
我想在我的引用DataFrame中查找每个变量名称,如果存在则返回相应的Standard_name,或者如果表中尚未引用该变量,则保留原始变量。
因此,上述虚拟示例的预期结果应为:
[Pressure, 'Speed', Altitude]
这在常规Python Pandas中很容易做到,但是我不知道如何在Spark中做到这一点,在Spark中您不应该考虑行索引。
在此先感谢您的帮助。
答案 0 :(得分:0)
尽管我同意上面的mayank agrawal的评论,但我还是尝试在Spark中解决此问题。
我改编了this solution以在大型词典中提取具有标准名称的每个变体的所有成对对应关系。然后,我将字典映射到标准头文件create a new column的数据集头文件上。
因此解决方案是:
from pyspark.sql import Row
from pyspark.sql.types import *
import pyspark.sql.functions as F
from itertools import chain
key_value_map = F.udf(lambda maps: {key:f[key] for f in maps for key in f},
MapType(StringType(),StringType()))
map_df = variable_df
.agg(F.collect_list(F.create_map(list(chain.from_iterable([[key, 'Standard'] for key in var_df.columns[2:]])))).alias('maps'))
.agg(F.collect_list(key_value_map('maps')))
result_dict = map_df.collect()
ref_dict = result_dict[0][0][0]
corresp_df = header_df
.withColumn('new_header', F.create_map([F.lit(x) for x in chain(*ref_dict.items())]).getItem(F.col('old_header')))
.withColumn("new_header", F.coalesce(F.col('new_header'), F.col('old_header')))
new_columns = corresp_df.select('new_header').rdd.flatMap(lambda row : row).collect()
renamed_df = data_df.toDF(*new_columns)
参考文献: