Я использую pyspark 2.4.3 с python 2
Как объединить два кадра данных и объединить столбцы, чтобы отразить их источники во вложенной структуре?
Я создал схему для применения к каждому столбцу. Но я не уверен, как его применить, поскольку для этого требуется информация из другого столбца.
схема данных 1 и 2:
root
|-- id: long
|-- tag: string
|-- container: string
|-- color: string
|-- count: long
входные файлы
operator1.json
{"color":"blue","container":"abc123","count":1,"id":1,"tag":"op1"}
{"color":"grey","container":"abc123","count":2,"id":2,"tag":"op1"}
{"color":"red","container":"abc333","count":1,"id":3,"tag":"op1"}
operator2.json
{"color":"","container":"abc123","count":3,"id":1,"tag":"op2"}
{"color":"grey","container":"abc999","count":2,"id":2,"tag":"op2"}
{"color":"red","container":"abc333","count":1,"id":3,"tag":"op2"}
df1: id | tag | container | color | count
-----------------------------------------
1 | op1 | abc123 | blue | 1
2 | op1 | abc124 | grey | 2
3 | op1 | abc333 | red | 1
df1: id | tag | container | color | count
-----------------------------------------
1 | op2 | abc123 | | 3
2 | op2 | abc999 | grey | 2
3 | op2 | abc333 | red | 1
То, что я хотел бы получить, это фрейм данных, который имеет вложенную структуру для каждого столбца. Ниже приведено описание того, что я пытаюсь получить
+-------------------------------------------------+--------------------------------------------------------------+-------------------------------------------+---+----------+
|color |container |count |id |tags |
+-------------------------------------------------+--------------------------------------------------------------+-------------------------------------------+---+----------+
|[false, [[op1, String, blue], [op2, String, ]], ]|[true, [[op1, String, abc123], [op2, String, abc123]], abc123]|[false, [[op1, Long, 1], [op2, Long, 3]], ]|1 |[op1, op2]|
+-------------------------------------------------+--------------------------------------------------------------+-------------------------------------------+---+----------+
root
|-- color: struct (nullable = true)
| |-- match: boolean (nullable = true)
| |-- tags: array (nullable = true)
| | |-- element: struct (containsNull = true)
| | | |-- tag: string (nullable = true)
| | | |-- type: string (nullable = true)
| | | |-- value: string (nullable = true)
| |-- value: string (nullable = true)
|-- container: struct (nullable = true)
| |-- match: boolean (nullable = true)
| |-- tags: array (nullable = true)
| | |-- element: struct (containsNull = true)
| | | |-- tag: string (nullable = true)
| | | |-- type: string (nullable = true)
| | | |-- value: string (nullable = true)
| |-- value: string (nullable = true)
|-- count: struct (nullable = true)
| |-- match: boolean (nullable = true)
| |-- tags: array (nullable = true)
| | |-- element: struct (containsNull = true)
| | | |-- tag: string (nullable = true)
| | | |-- type: string (nullable = true)
| | | |-- value: string (nullable = true)
| |-- value: string (nullable = true)
|-- id: long (nullable = true)
|-- tags: array (nullable = true)
| |-- element: string (containsNull = true)
Не очень хорошо владеет Python. Но у меня есть основы, где я могу как-то обойтись.
Я пытался объединить два кадра данных по идентификатору, но не нашел способа объединить соответствующие столбцы в один.
Например.
new_col_schema = t.StructType([ t.StructField('match', t.BooleanType(), True),
t.StructField('value', t.StringType(), True),
t.StructField('tags', t.ArrayType(
t.StructType([
t.StructField('tag', t.StringType(), True),
t.StructField('value', t.StringType(), True),
t.StructField('type', t.StringType(), True)
])
))
])
def make_nested(o1, v1, o2, v2):
match = False
value = ''
if v1 == v2:
match=True
value = v1
return {'match': match, 'value': value, 'tags', [{'tag': o1, 'value': v1, 'type': type(v1)},{'tag':o2, 'value':v2, 'type':type(v2)}]}
nestudf = f.udf(make_nested, t.StructType())
df1 = sqlContext.read.json('/data/op1.json')
df2 = sqlContext.read.json('/data/op2.json')
df = df1.join(df2, ['id'])
# see if I can get one column to be nested
df = df.withColumn('
Это создаст кадр данных с дублирующимися столбцами, оставляя то, что я ищу, доступным, но недоступным.
df = df.withColumn('container', nestudf(df1.op, df1.container, df2.op, df2.container))
Но, как я понял. Я думаю, что единственная причина, по которой дубликаты столбцов после объединения доступны. Это так можно уронить. Кроме этого, у меня не было доступа к ним или их значениям для моей функции.
Я надеюсь, что смогу вложить столбцы окончательного фрейма данных со связанной с ними информацией о столбцах, связанной с их идентификатором. Фрейм данных будет записан в файл json, поэтому он должен выглядеть примерно так:
{"id":1,
"tags" : ["op1", "op2"],
"container" : {
"match": true,
"value": "abc123",
"tags" : [
{"tag": "op1",
"value": "abc123",
"type" : "String"
},
{"tag": "op2",
"value": "abc123",
"type" : "String"
}
]
},
"color" : {
"match": false,
"value": "",
"tags" : [
{"tag": "op1",
"value": "blue",
"type" : "String"
},
{"tag": "op2",
"value": "",
"type" : "String"
}
]
},
"count" : {
"match": false,
"value": "",
"tags" : [
{"tag": "op1",
"value": "1",
"type" : "Integer"
},
{"tag": "op2",
"value": "3",
"type" : "Integer"
}
]
}
},
{'id': 2, ......