如何通过索引从Spark数据框中删除列,在列中可以复制列名?

时间:2020-01-23 16:38:48

标签: dataframe apache-spark pyspark

我有一个Spark数据框,只想删除最后一列。

我尝试了

df.drop(df.columns.last)` 

但出现错误AttributeError: 'list' object has no attribute 'last'

我也尝试过:

df = df.drop(df.columns[-1])

但这会删除所有名称与姓氏相同的列。

使用Spark 2.4

2 个答案:

答案 0 :(得分:1)

这是一种您可以按索引删除任何列的方法。

假设您具有以下数据框:

np.random.seed(1)
data = np.random.randint(0, 10, size=(3,3))

df = spark.createDataFrame(data.astype(int).tolist(), ["a", "b", "a"])
df.show()
#+---+---+---+
#|  a|  b|  a|
#+---+---+---+
#|  5|  8|  9|
#|  5|  0|  0|
#|  1|  7|  6|
#+---+---+---+

首先保存原始列名。

colnames = df.columns
print(colnames)
#['a', 'b', 'a']

然后使用range rename all of the columns in the DataFrame,以便新的列名是唯一的(它们将只是列索引)。

df = df.toDF(*map(str, range(len(colnames))))
print(df.columns)
#['0', '1', '2']

现在放置最后一列,并使用第一步中保存的列名(不包括最后一列)重命名列。

df = df.drop(df.columns[-1]).toDF(*colnames[:-1])
df.show()
#+---+---+
#|  a|  b|
#+---+---+
#|  5|  8|
#|  5|  0|
#|  1|  7|
#+---+---+

由于我们使用range重命名,因此您可以轻松地将其扩展到任何索引。


出于解释目的,我将其分解为多个步骤,但您也可以按以下步骤更紧凑地进行操作:

colnames = df.columns
df = df.toDF(*map(str, range(len(colnames))))\
    .drop(str(len(colnames)-1))\
    .toDF(*colnames[:-1])

答案 1 :(得分:0)

最好按名称删除一列。诸如withColumn之类的某些操作可以更改列的顺序。如果数据帧中有来自联接的重复名称,则用dataframe.column_name引用该列,而不用"columnName"引用该列,这会造成歧义。

df3 = df1.join(df2, df1.c1 == df2.c1).drop(df2.c1)

一般df.drop(df.columnName)