如何修复火花可怕的误解csv?

问题描述 投票:2回答:1

我有两个csv文件,一个包含电影的关键字,另一个包含演员和工作人员。 keywords.csv文件如下所示:

$ head -n 3 keywords.csv
id,keywords
862,"[{'id': 931, 'name': 'jealousy'}, {'id': 4290, 'name': 'toy'}, {'id': 5202, 'name': 'boy'}, {'id': 6054, 'name': 'friendship'}, {'id': 9713, 'name': 'friends'}, {'id': 9823, 'name': 'rivalry'}, {'id': 165503, 'name': 'boy next door'}, {'id': 170722, 'name': 'new toy'}, {'id': 187065, 'name': 'toy comes to life'}]"
8844,"[{'id': 10090, 'name': 'board game'}, {'id': 10941, 'name': 'disappearance'}, {'id': 15101, 'name': ""based on children's book""}, {'id': 33467, 'name': 'new home'}, {'id': 158086, 'name': 'recluse'}, {'id': 158091, 'name': 'giant insect'}]"

credits.csv文件如下所示:

$ head -n 2 credits.csv
cast,crew,id
"[{'cast_id': 14, 'character': 'Woody (voice)', 'credit_id': '52fe4284c3a36847f8024f95', 'gender': 2, 'id': 31, 'name': 'Tom Hanks', 'order': 0, 'profile_path': '/pQFoyx7rp09CJTAb932F2g8Nlho.jpg'}, {'cast_id': 15, 'character': 'Buzz Lightyear (voice)', 'credit_id': '52fe4284c3a36847f8024f99', 'gender': 2, 'id': 12898, 'name': 'Tim Allen', 'order': 1, 'profile_path': '/uX2xVf6pMmPepxnvFWyBtjexzgY.jpg'}]", 1

两者都是正确形成的csvs,pandas没有读入的问题.Spark读取它们像这样:

spark.read
  .option("quote", "\"")
  .option("delimiter", ",")
  .option("header", "true")
  .csv("keywords.csv")
  .show(2)

输出:

+-------+--------------------+
|movieId|            keywords|
+-------+--------------------+
|    862|[{'id': 931, 'nam...|
|   8844|"[{'id': 10090, '...|
+-------+--------------------+

它清楚地显示了第一行和第二行之间的差异(注意"字符的存在/不存在。这可以通过包含字符串替换的简单udf来修复。

对于credits.csv来说,它可怕的错误:

spark.read
  .option("quote", "\"")
  .option("delimiter", ",")
  .option("header", "true")
  .csv("credits.csv")
  .show(2)

输出:

+--------------------+--------------------+--------------------+
|                cast|                crew|             movieId|
+--------------------+--------------------+--------------------+
|[{'cast_id': 14, ...|"[{'credit_id': '...| 'profile_path': ...|
|[{'cast_id': 1, '...|[{'credit_id': '5...|                8844|
+--------------------+--------------------+--------------------+

列被打破了......

如何在不破坏列的情况下正确阅读(如果可能)?我很惊讶pandas没有问题,而火花惨不忍睹。

scala csv apache-spark pyspark
1个回答
3
投票

对于第一个文件,您使用不正确的转义字符 - csv中的默认值是\,您的文件使用"

>>> (spark.read
...   .option("escape", '"')
...   .option("header", "true")
...   .csv("keywords.csv")
...   .show(2))
...   
+----+--------------------+
|  id|            keywords|
+----+--------------------+
| 862|[{'id': 931, 'nam...|
|8844|[{'id': 10090, 'n...|
+----+--------------------+

在第二个文件(credits.csv)中存在同样的问题,并且标题中的字段数量与数据不匹配(commentKirk Broadhurst)它无法在Spark中正确加载:

>>> (spark.read
...   .option("escape", '"')
...   .option("header", "true")
...   .csv("credits.csv")
...   .show(2))
...   
+--------------------+----+----+
|                cast|crew|  id|
+--------------------+----+----+
|[{'cast_id': 14, ...|   1|null|
+--------------------+----+----+

和熊猫一样:

>>> pd.read_csv("credits.csv")
                                                cast  crew  id
0  [{'cast_id': 14, 'character': 'Woody (voice)',...     1 NaN
© www.soinside.com 2019 - 2024. All rights reserved.