PySpark:执行联合时列数据类型发生变化

Clo*_*ave 3 python apache-spark pyspark

我在列表中存储了三个数据帧data_multi。每个数据框都有相同的列名和相同的数据类型

>>> set(data_multi[0].columns) == set(data_multi[1].columns)  == set(data_multi[2].columns)
True
Run Code Online (Sandbox Code Playgroud)

dtypes(仅显示一列)

>>> data_multi[0].select('aml_id_key_12739').dtypes
[('aml_id_key_12739', 'bigint')]

>>> data_multi[1].select('aml_id_key_12739').dtypes
[('aml_id_key_12739', 'bigint')]

>>> data_multi[2].select('aml_id_key_12739').dtypes
[('aml_id_key_12739', 'bigint')]
Run Code Online (Sandbox Code Playgroud)

我复制了 SO 上的帖子中提到的一个函数,该函数联合(rbinds)所有数据帧

def unionAll(*dfs):
    return reduce(DataFrame.unionAll, dfs)
Run Code Online (Sandbox Code Playgroud)

使用这个,我将三个数据帧联合起来得到一个 data_single = unionAll(*ddata_multi)

这是我面临问题的地方。aml_id_key_12739每个数据帧中的列是 a但'bigint'在并集之后它就变成了'double'

>>> pprint(data_single.select('aml_id_key_12739').dtypes)
[('aml_id_key_12739', 'double')]
Run Code Online (Sandbox Code Playgroud)

因此我的整个 id 列都搞乱了。我在忽略什么?

Clo*_*ave 7

我发现了这个错误。问题是 Spark 将简单地附加数据帧。它不会使用列名称进行追加。

如果您使用联合,那么您应该确保数据框中的列以相同的顺序出现,因为附加似乎是按照它们出现的顺序发生的。

在此示例中,我颠倒了第二个 dataframe( ) 中的列和值的顺序df_2,然后采用并集。

>>> df_1 = spark.createDataFrame([['a',1]], ['col_1', 'col_2'])
>>> df_2 = spark.createDataFrame([[2,'b']], ['col_2', 'col_1'])
>>> df_3 = unionAll(*[df_1, df_2])
>>> df_3
DataFrame[col_1: string, col_2: string]
>>> df_3.show()
+-----+-----+
|col_1|col_2|
+-----+-----+
|    a|    1|
|    2|    b|
+-----+-----+
Run Code Online (Sandbox Code Playgroud)

现在,当我使用正确的顺序时,我得到了预期的输出

>>> df_3 = unionAll(*[df_1.select(*['col_1', 'col_2']), df_2.select(*['col_1', 'col_2'])])
>>> df_3.show()
+-----+-----+                                                                   
|col_1|col_2|
+-----+-----+
|    a|    1|
|    b|    2|
+-----+-----+
Run Code Online (Sandbox Code Playgroud)