Dataframe 如何通过索引从spark数据框中删除列名可以重复的列?

Dataframe 如何通过索引从spark数据框中删除列名可以重复的列?,dataframe,apache-spark,pyspark,Dataframe,Apache Spark,Pyspark,我有一个spark数据帧,只想删除最后一列 df = df.drop(df.columns[-1]).toDF(*colnames[:-1]) df.show() #+---+---+ #| a| b| #+---+---+ #| 5| 8| #| 5| 0| #| 1| 7| #+---+---+ 我试过了 df.drop(df.columns.last)` 但出现错误AttributeError:“list”对象没有属性“last” 我还尝试: df = df.drop

我有一个spark数据帧,只想删除最后一列

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

df.drop(df.columns.last)` 
但出现错误AttributeError:“list”对象没有属性“last”

我还尝试:

df = df.drop(df.columns[-1])
但这会删除所有与上次同名的列


使用Spark 2.4,最好按名称删除一列。某些操作(如withColumn)可以更改列的顺序。如果数据帧具有从联接中产生的重复名称,则按dataframe.column\u名称引用列,而不是按columnName引用列,这会导致歧义

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


一般来说,df.dropdf.columnName

这里有一种方法,可以通过索引删除任何列

假设您有以下数据帧:

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,使新列名是唯一的,它们只是列索引

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])

最好是直呼其名。withColumn可以更改columns@Joe我建议如下:1将列名保存到列表中:colnames=df.columns 2重命名列,使其名称唯一:df=df.toDF*rangecolnames 3删除最后一列df=df.dropdf.columns[-1]4将列重命名回原始列:df=df.toDF*cols[:-1]。如果问题重新打开,请Ping me,我将发布答案。@pault我重新打开的问题列名可能不明确,因为此处将有两列名称为c1。如果我执行df2。删除“c1”,则其不明确。但是如果我做了df2.dropdf2.C1,那么它就不是了。请尝试。我需要的例子和火花版本复制。