У меня есть фреймворк pyspark, состоящий из одного столбца, называемого json
, где каждая строка является строкой unicode json. Я хотел бы проанализировать каждую строку и вернуть новую фреймворк данных, где каждая строка является разобранным json.
# Sample Data Frame
jstr1 = u'{"header":{"id":12345,"foo":"bar"},"body":{"id":111000,"name":"foobar","sub_json":{"id":54321,"sub_sub_json":{"col1":20,"col2":"somethong"}}}}'
jstr2 = u'{"header":{"id":12346,"foo":"baz"},"body":{"id":111002,"name":"barfoo","sub_json":{"id":23456,"sub_sub_json":{"col1":30,"col2":"something else"}}}}'
jstr3 = u'{"header":{"id":43256,"foo":"foobaz"},"body":{"id":20192,"name":"bazbar","sub_json":{"id":39283,"sub_sub_json":{"col1":50,"col2":"another thing"}}}}'
df = sql_context.createDataFrame([Row(json=jstr1),Row(json=jstr2),Row(json=jstr3)])
Я попытался сопоставить каждую строку с json.loads
:
(df
.select('json')
.rdd
.map(lambda x: json.loads(x))
.toDF()
).show()
Но это возвращает a TypeError: expected string or buffer
Я подозреваю, что часть проблемы заключается в том, что при преобразовании из dataframe
в rdd
информация о схеме теряется, поэтому я также попытался вручную ввести информацию о схеме:
schema = StructType([StructField('json', StringType(), True)])
rdd = (df
.select('json')
.rdd
.map(lambda x: json.loads(x))
)
new_df = sql_context.createDataFrame(rdd, schema)
new_df.show()
Но я получаю тот же TypeError
.
Рассматривая этот ответ, похоже, что выравнивание строк с flatMap
может быть полезно здесь, но я не уверен в этом:
schema = StructType([StructField('json', StringType(), True)])
rdd = (df
.select('json')
.rdd
.flatMap(lambda x: x)
.flatMap(lambda x: json.loads(x))
.map(lambda x: x.get('body'))
)
new_df = sql_context.createDataFrame(rdd, schema)
new_df.show()
Я получаю эту ошибку: AttributeError: 'unicode' object has no attribute 'get'
.