如何从pyspark中的JSON文件动态传递Dataframe列值?

时间:2018-04-17 11:47:21

标签: python apache-spark dataframe pyspark spark-dataframe

我正在使用下面的代码创建数据框,它正在按预期工作。

我的数据集是'testdata'

1|123
2|223
3|323
4|423

from pyspark.sql import SQLContext,SparkSession
from pyspark.sql import Row
spark = SparkSession.builder.appName("test").getOrCreate()
sc = spark.sparkContext
sqlContext = SQLContext(sc)
df_transac = spark.createDataFrame(sc.textFile("testdata").map( lambda x: x.split("|")[:2]).map( lambda r: Row( testA = r[0],testb = r[1])))
df_transac.show()

+---------+---------+
|   testA | testB   |
+---------+---------+
|      123|        1|
|      223|        2|
|      323|        3|
|      423|        4|
+---------+---------+

上面的数据帧创建时间testA,testB是硬编码的列名,但我想从json中获取这些值,所以我尝试了以下方式。 我的json文件testjson.json:

{
    "column1":"testcolumn1"
    ,"column2":"testcolumn2"
}   

然后我尝试通过执行下面的代码来创建数据框, 但它的投掷错误。

import json
from pyspark.sql import SQLContext,SparkSession
from pyspark.sql import Row
with open(testjson.json) as spec_data:
    jsn = json.load(spec_data)
spark = SparkSession.builder.appName("test").getOrCreate()
sc = spark.sparkContext
sqlContext = SQLContext(sc)
df_transac = spark.createDataFrame(sc.textFile("testdata").map( lambda x: x.split("|")[:2]).map( lambda r: Row( jsn['column1'] = r[0], jsn['column2'] = r[1])))

抛出错误如:SyntaxError:keyword不能是表达式。

我的预期输出是:

+-----------+-----------+
|testcolumn1|testcolumn2|
+-----------+-----------+
|          1|        123|
|          2|        223|
|          3|        323|
|          4|        423|
+-----------+-----------+

请帮忙解决这个问题。

提前致谢。

2 个答案:

答案 0 :(得分:1)

正如例外所述 - 你不能将表达式用作关键字,所以:

Row( jsn['column1'] = r[0], jsn['column2'] = r[1])

不是有效的Python代码。

您可以使用替代构造函数然后应用参数:

Row(jsn['column1'], jsn['column2'])(r[0], r[1])

但总的来说,

会更好
tmp = spark.read.option("delimiter", "|").csv("testdata")
df = tmp.select(tmp.columns[2:]).toDF(jsn['column1'], jsn['column2'])

答案 1 :(得分:0)

df_transac = spark.createDataFrame(sc.textFile("testdata").map( lambda x: x.split("|")[:2]).map( lambda r: Row( jsn['column1'] = r[0], jsn['column2'] = r[1])))

使用以下代码解决问题,而不是上面的代码。

c1=spec['column1']
c2=spec['column2']
a=sc.textFile("testdata").map( lambda x: x.split("|")[:2])
data = sqlContext.createDataFrame(a,[c1, c2])