pyspark withColumn,如何更改列名

时间:2018-09-13 09:55:33

标签: dataframe pyspark columnname

有什么方法可以使用pyspark 2.1.0创建/填充列,其中列名是其他列的值? 我尝试了以下

def createNewColumnsFromValues(dataFrame, colName, targetColName):
  """
  Set value of column colName to targetColName's value
  """
  cols = dataFrame.columns
  #df = dataFrame.withColumn(f.col(colName), f.col(targetColName))
  df = dataFrame.withColumn('x', f.col(targetColName))
  return df

在调用方法时出现错误的注释行不起作用

TypeError: 'Column' object is not callable

而固定名称(作为字符串)则没有问题。关于如何使列名也不仅仅是另一个值的任何想法?我还尝试使用UDF函数定义作为解决方法,但没有成功的结果。

感谢帮助!

编辑:

from pyspark.sql import functions as f

2 个答案:

答案 0 :(得分:0)

您可能想尝试以下代码:

test_df = spark.createDataFrame([
    (1,"2",5,1),(3,"4",7,8),              
    ], ("col1","col2","col3","col4"))

def createNewColumnsFromValues(dataFrame, sourceCol, colName, targetCol):
    """
    Set value column colName to targetCol
    """
    for value in sourceCol:
        dataFrame = dataFrame.withColumn(str(value[0]), when(col(colName)==value[0], targetCol).otherwise(None))

    return dataFrame

createNewColumnsFromValues(test_df, test_df.select("col4").collect(), "col4", test_df["col3"]).show()   

这里的技巧是执行select("COLUMNNAME").collect()以获取列中值的列表。然后colName包含此列表,该列表是行的列表,其中每一行都有一个元素。因此,您可以直接遍历列表并访问位置0的元素。在这种情况下,必须将字符串强制转换为字符串,以确保新列的列名是字符串。目标列用于各个单独列的值。因此结果将如下所示:

+----+----+----+----+----+----+
|col1|col2|col3|col4|   1|   8|
+----+----+----+----+----+----+
|   1|   2|   5|   1|   5|null|
|   3|   4|   7|   8|null|   7|
+----+----+----+----+----+----+

答案 1 :(得分:0)

我想出了一种解决方案,该解决方案可以很好地扩展我需要列的几个(或不很多)不同值。确实是这种情况,否则列数会爆炸。

def createNewColumnsFromValues(dataFrame, colName, targetCol):
  distinctValues = dataFrame.select(colName).distinct().collect()
  for value in distinctValues:
    dataFrame = dataFrame.withColumn(str(value[0]), f.when(f.col(colName) == value[0], f.col(targetCol)).otherwise(f.lit(None)))

return dataFrame