当前位置: 首页 > 知识库问答 >
问题:

在spark csv数据框中删除列

凤修筠
2023-03-14

我有一个数据框架,我连接到它的所有字段。

连接后它成为另一个数据帧,最后我将其输出写入csv文件,并在其两列上进行分区。它的一列存在于第一个数据帧中,我不想包含在最终输出中。

这是我的代码

val dfMainOutput = df1resultFinal.join(latestForEachKey, Seq("LineItem_organizationId", "LineItem_lineItemId"), "outer")
      .select($"LineItem_organizationId", $"LineItem_lineItemId",
       when($"DataPartition_1".isNotNull, $"DataPartition_1").otherwise($"DataPartition".cast(DataTypes.StringType)).as("DataPartition"),
       when($"StatementTypeCode_1".isNotNull, $"StatementTypeCode_1").otherwise($"StatementTypeCode").as("StatementTypeCode"),
       when($"FFAction_1".isNotNull, concat(col("FFAction_1"), lit("|!|"))).otherwise(concat(col("FFAction"), lit("|!|"))).as("FFAction"))
       .filter(!$"FFAction".contains("D"))

在这里,我连接并创建另一个数据帧:

val dfMainOutputFinal = dfMainOutput.select($"DataPartition", $"StatementTypeCode",concat_ws("|^|", dfMainOutput.schema.fieldNames.map(c => col(c)): _*).as("concatenated"))     

这就是我尝试过的

dfMainOutputFinal
  .drop("DataPartition")
  .write
  .partitionBy("DataPartition","StatementTypeCode")
  .format("csv")
  .option("header","true")
  .option("encoding", "\ufeff")
  .option("codec", "gzip")
  .save("path to csv")

现在我不希望在我的输出中的数据分区列。

我正在基于DataPartition进行分区,所以我没有得到,但因为DataPartition存在于主数据帧中,所以我在输出中得到它。

问题1:如何忽略Dataframe中的列

问题2:在写入实际数据之前,是否有任何方法在csv输出文件中添加“\ufeff”,以便我的编码格式成为UTF-8-BOM。

根据建议的答案

这是我已经尝试过的

 val dfMainOutputFinal = dfMainOutput.select($"DataPartition", $"StatementTypeCode",concat_ws("|^|", dfMainOutput.schema.filter(_ != "DataPartition").fieldNames.map(c => col(c)): _*).as("concatenated"))

但低于错误

<console>:238: error: value fieldNames is not a member of Seq[org.apache.spark.sql.types.StructField]
               val dfMainOutputFinal = dfMainOutput.select($"DataPartition", $"StatementTypeCode",concat_ws("|^|", dfMainOutput.schema.filter(_ != "DataPartition").fieldNames.map(c => col(c)): _*).as("concatenated"))

下面是我是否必须删除最终输出中的两列的问题

  val dfMainOutputFinal = dfMainOutput.select($"DataPartition","PartitionYear",concat_ws("|^|", dfMainOutput.schema.fieldNames.filter(_ != "DataPartition","PartitionYear").map(c => col(c)): _*).as("concatenated"))

共有2个答案

杨和蔼
2023-03-14

问题1:如何忽略Dataframe中的列

Ans:

val df = sc.parallelize(List(Person(1,2,3), Person(4,5,6))).toDF("age", "height", "weight")

df.columns
df.show()



+---+------+------+
|age|height|weight|
+---+------+------+
|  1|     2|     3|
|  4|     5|     6|
+---+------+------+


val df_new=df.select("age", "height")
    df_new.columns
    df_new.show()

+---+------+
|age|height|
+---+------+
|  1|     2|
|  4|     5|
+---+------+

df: org.apache.spark.sql.DataFrame = [age: int, height: int ... 1 more field]
df_new: org.apache.spark.sql.DataFrame = [age: int, height: int]

问题2:有没有办法在写入我的实际数据之前在csv输出文件中添加“\ufeff”,这样我的编码格式就会变成UTF-8-BOM。

Ans:

 String path= "/data/vaquarkhan/input/unicode.csv";

 String outputPath = "file:/data/vaquarkhan/output/output.csv";
    getSparkSession()
      .read()
      .option("inferSchema", "true")
      .option("header", "true")
      .option("encoding", "UTF-8")
      .csv(path)
      .write()
      .mode(SaveMode.Overwrite)
      .csv(outputPath);
}
翁心思
2023-03-14

问题一:

您在df.write.partitionBy()中使用的列不会添加到最终的csv文件中。它们会自动被忽略,因为数据是在文件结构中编码的。但是,如果您的意思是将其从concat_ws(从而从文件中)中删除,则可以做一个小的更改:

concat_ws("|^|", 
  dfMainOutput.schema.fieldNames
    .filter(_ != "DataPartition")
    .map(c => col(c)): _*).as("concatenated"))

在这里,列数据分区在连接之前被过滤掉。

问题二:

Spark似乎不支持UTF-8 BOM,并且在读取具有该格式的文件时似乎会导致问题。除了在Spark完成后编写脚本添加BOM字节外,我想不出任何简单的方法来将BOM字节添加到每个csv文件中。我建议只使用普通的UTF-8格式。

dfMainOutputFinal.write.partitionBy("DataPartition","StatementTypeCode")
  .format("csv")
  .option("header", "true")
  .option("encoding", "UTF-8")
  .option("codec", "gzip")
  .save("path to csv")

此外,根据Unicode标准,不建议使用BOM。

... UTF-8既不需要也不建议使用BOM,但在UTF-8数据从使用BOM的其他编码形式转换而来或BOM用作UTF-8签名的情况下可能会遇到。

 类似资料:
  • 问题内容: 我有数据框: df 如何删除列名,并从该数据帧?一种方法是将其写入csv文件,然后在指定header = None的情况下读取它。有没有一种方法,而无需写到csv并重新读取? 问题答案: 我认为你不能删除列名,只能通过重新设置有: 这与使用和相同: 下一个解决方案:

  • 我有一个名为“mydata”的数据框,看起来像这样: 我想删除第2、4、6行。例如,像这样:

  • 问题内容: 我可以使用 功能来删除将部分或全部列设置为的行。是否存在用于删除所有列的值为0的行的等效函数? 在此示例中,我们要删除数据帧的前4行。 谢谢! 问题答案: 事实证明,这可以向量化的方式很好地表达:

  • 问题内容: 我有一个来自AG列的数据文件,如下所示,但是当我用它读取数据时,它毫无理由地在末尾打印了一个额外的列。 我已经多次查看过我的数据文件,但是其他任何列中都没有多余的数据。我在阅读时应如何删除此多余的列?谢谢 问题答案: df = df.loc[:, ~df.columns.str.contains(‘^Unnamed’)] 如果CSV文件的第一列具有索引值,则可以执行以下操作:

  • 问题内容: 我需要删除pandas中数据框的前三行。 我知道会删除最后一行,但我不知道如何删除前n行。 问题答案: 用途: 将为您提供一个没有前三行的新df。

  • 本文向大家介绍如何删除R数据框中的行?,包括了如何删除R数据框中的行?的使用技巧和注意事项,需要的朋友参考一下 这可以通过使用方括号来完成。 示例 假设我们要删除第4、7和9行。我们将执行以下操作-