如何修复火花可怕地误解 csv?
Posted
技术标签:
【中文标题】如何修复火花可怕地误解 csv?【英文标题】:How to fix spark horribly misinterpreting csv? 【发布时间】:2017-12-15 20:23:10 【问题描述】:我有两个 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
两者都是格式正确的 csv,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
没有问题,而 spark 却惨遭失败。
【问题讨论】:
您的credits.csv
样本,假设我从表面上看引号字符,只有两个字段。第一个字段字符串看起来像一个包含两个字典的列表;第二个字段是一个整数。
【参考方案1】:
对于第一个文件,您使用了错误的转义字符 - 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
)中也有同样的问题,另外头部中的字段数与数据不匹配(comment by Kirk 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
【讨论】:
以上是关于如何修复火花可怕地误解 csv?的主要内容,如果未能解决你的问题,请参考以下文章