需要从pyspark的数据框中删除重复的列

时间:2019-05-31 15:39:15

标签: python-3.x apache-spark pyspark apache-spark-sql

我有一个包含432列的数据框,并且有24个重复的列。

  1. df_tickets->共有432列
  2. duplicatecols->这具有df_tickets中的重复项。

我想删除重复的df_tickets中的cols。因此df_tickets应该只包含432-24 = 408列。

我用下面的代码尝试了此操作,但是它抛出错误。

df_tickets.select([c for c in df_tickets.columns if c not in duplicatecols]).show()

错误是

An error occurred while calling o1657.showString.
: org.apache.spark.sql.catalyst.errors.package$TreeNodeException: execute, tree:
HashAggregate(keys=[ms_bvoip_order_extension_id#953, ms_order_id#954...........

有人可以帮我吗?

3 个答案:

答案 0 :(得分:0)

以下解决方案应消除重复项,并保留输入df的列顺序。

加载一些示例数据

df_tickets = spark.createDataFrame([(1,2,3,4,5)],['a','b','c','d','e'])
duplicatecols = spark.createDataFrame([(1,3,5)],['a','c','e'])

检查df模式

df_tickets.printSchema()
root
 |-- a: long (nullable = true)
 |-- b: long (nullable = true)
 |-- c: long (nullable = true)
 |-- d: long (nullable = true)
 |-- e: long (nullable = true)

删除重复的列

duplicatecols.printSchema()

root
 |-- a: long (nullable = true)
 |-- c: long (nullable = true)
 |-- e: long (nullable = true)

outCols = [x for x in df_tickets.columns if x not in set(duplicatecols.columns)]

df_tickets[outCols].show()

+---+---+
|  b|  d|
+---+---+
|  2|  4|
+---+---+

答案 1 :(得分:0)

您可能必须重命名某些重复的列才能过滤重复的列。否则,您可能要取消选择重复列中的所有列,而您可能希望每个保留一列。以下是一种可能有用的方法:

# an example dataframe
cols = list('abcaded')
df_ticket = spark.createDataFrame([tuple(i for i in range(len(cols)))], cols)
>>> df_ticket.show()
#+---+---+---+---+---+---+---+
#|  a|  b|  c|  a|  d|  e|  d|
#+---+---+---+---+---+---+---+
#|  0|  1|  2|  3|  4|  5|  6|
#+---+---+---+---+---+---+---+

# unless you just want to filter a subset of all duplicate columns
# this list is probably not useful
duplicatecols = list('ad')

# create cols_new so that seen columns will have a suffix '_dup'
cols_new = [] 
seen = set()
for c in df_ticket.columns:
    cols_new.append('{}_dup'.format(c) if c in seen else c)
    seen.add(c)

>>> cols_new
#['a', 'b', 'c', 'a_dup', 'd', 'e', 'd_dup']

然后根据新的列名过滤结果

>>> df_ticket.toDF(*cols_new).select(*[c for c in cols_new if not c.endswith('_dup')]).show()
#+---+---+---+---+---+
#|  a|  b|  c|  d|  e|
#+---+---+---+---+---+
#|  0|  1|  2|  4|  5|
#+---+---+---+---+---+

这将使列的第一列具有相同的列名。如果要保留最后一个,应该很容易解决。理想情况下,您应该在创建具有重复列名的数据框之前调整列名。

答案 2 :(得分:-1)

尝试:

select_list = list(set(df_tickets.columns)-set(duplicatecols))
df_tickets.select(select_list).show()

让我知道这是否对您有用。