我已经加载了一个实木复合地板文件并创建了一个数据框,如下所示
----------------------------------------------------------------------
time | data1 | data2
-----------------------------------------------------------------------
1-40 | [ lion-> 34, bear -> 2 ] | [ monkey -> [9,23], goose -> [4,5] ]
因此,data1列的数据类型为string->integer
映射,而data2列的数据类型为string->array
映射。
我想将上面的数据框分解为下面的结构
------------------------
time | key | val
------------------------
1-40 | lion | 34
1-40 | bear | 2
1-40 | monkey_0 | 9
1-40 | monkey_1 | 23
1-40 | goose_0 | 4
1-40 | goose_1 | 5
我尝试通过在pyspark中使用udfs将data1和data2转换为与string->array
相同的数据类型,然后按如下所示展开列
def to_map(col1, col2):
for i in col1.keys():
col2[i] = [col1[i]]
return col2
caster= udf(to_map,MapType(StringType(),ArrayType(IntegerType())))
pm_df = pm_df.withColumn("animals", caster('data1', 'data2'))
pm_df.select('time',explode(col('animals')))
我还尝试通过假设配置单元sql比使用pysprak udfs具有更高的性能来使用配置单元sql。
rdd = spark.sparkContext.parallelize([[datetime.datetime.now(), {'lion': 34, 'bear': 2}, {'monkey': [9, 23], 'goose':[4,5]} ]])
df = rdd.toDF(fields)
df.createOrReplaceTempView("df")
df = spark.sql("select time, explode(data1), data2 from df")
df.createOrReplaceTempView("df")
df = spark.sql("select time,key as animal,value,posexplode(data2) from df").show(truncate=False)
但是我对下面的结果感到困惑,并且不知道如何按照我的要求合并拆分的列。上面的配置单元sql的输出是:
+--------------------------+------+-----+---+------+-------+
|time |animal|value|pos|key |value |
+--------------------------+------+-----+---+------+-------+
|2019-06-12 19:23:00.169739|bear |2 |0 |goose |[4, 5] |
|2019-06-12 19:23:00.169739|bear |2 |1 |monkey|[9, 23]|
|2019-06-12 19:23:00.169739|lion |34 |0 |goose |[4, 5] |
|2019-06-12 19:23:00.169739|lion |34 |1 |monkey|[9, 23]|
+--------------------------+------+-----+---+------+-------+
我知道在使用python udfs时,python处理器和JVM之间的通信会产生很多开销。有什么方法可以使用内置函数或Hive sql达到上述预期结果。
答案 0 :(得分:2)
我将分别处理import os, sys
dir_path = os.path.dirname(os.path.realpath(__file__))
# Open a file
dirs = os.listdir(dir_path)
i=1
# This would print all the files and directories
for file in dirs:
if file!='VBA.xlsm' and file!='VBA.py' and file!='~$VBA.xlsm':
print(file) #print all the files
i=str(i) #change to string for file name
i=i + '.xls' #add extension
os.rename(file,i) #rename the file
size=len(i)
i=i[0:size-4] #remove the extension
i=int(i) #change back to numerical
i=i+1 #new numerical name
和data1
,然后 union 结果集:
data2