使用 OpenRefine 将 CSV 数据转换为嵌套 JSON
Turning CSV data into nested JSON using OpenRefine
所以我试图从 csv 格式解析一些天气数据并将其转换为嵌套的 JSON 格式。我目前有一个大型 csv 文件,其中包含以下列:站点 ID、月份,然后是数据的 30 列(每天)。我在顶部有一个带有基本标题的 header。我正在尝试将其转换为 json 格式,其中 Station ID 是键名,其中 1-12 个月是另一个键名,并且在其中显示 30 天中的每一天。我尝试了几个在线和可下载的 CSV 到 JSON,并花时间玩 OpenRefine,但无法弄清楚如何将 Station id 作为 header 然后嵌套月份,然后嵌套日期。以下是供参考的 CSV 数据示例:Station Name,Month,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
AQW00061705,1,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,825C,825C,825C,825C,825C,825C,825C,825C,825C,825C,826C,826C,826C
。
每个站点 ID 都有 12 个这样的列,这使得这个过程特别困难。如果有人有使用 OpenRefine 的经验,或将这种类型的结构化数据转换为 JSON,将不胜感激。
所以在 OpenRefine 中为此编写一个导出模板有点痛苦,但可以做到。
首先在 OpenRefine 项目中使用 Station Name 列上的 'Edit Cells -> Blank Down' 菜单选项
然后转到导出并选择 "Templating"
在 'Prefix' 部分只需输入 [
在行模板部分输入:
{{if(row.record.fromRowIndex==row.index,if(row.record.fromRowIndex>0,",","")+"{\"Station Name\" :"+ jsonize(cells["Station Name"].value)+",","")}}
{{jsonize(cells["Month"].value)}}:{
{{forEach(row.columnNames[2,33],v,jsonize(v)+": "+jsonize(cells[v].value)+if(v!="31",",",""))}}
}{{if(cells["Month"].value!="12",",","")}}
{{if(row.index+1==row.record.toRowIndex,unescape("}","html"),"")}}
将行分隔符部分留空
在 'Suffix' 部分只需输入 ]
这应该会给你有效的 JSON 比如:
[
{
"Station Name": "AQW00061705",
"1": {
"1": "824C",
"2": "824C",
"3": "824C",
"4": "824C",
"5": "824C",
等等
第一个“1”是月份,后面的“1”:“824C”等是天数和读数
我必须在此处添加大量逻辑才能使其正常工作 - 理论上,我认为更简单的版本应该可以正常工作,但我看到一些奇怪的行为导致无效 JSON -因此,我已经将所有逻辑工作到模板中的 GREL 中
所以我试图从 csv 格式解析一些天气数据并将其转换为嵌套的 JSON 格式。我目前有一个大型 csv 文件,其中包含以下列:站点 ID、月份,然后是数据的 30 列(每天)。我在顶部有一个带有基本标题的 header。我正在尝试将其转换为 json 格式,其中 Station ID 是键名,其中 1-12 个月是另一个键名,并且在其中显示 30 天中的每一天。我尝试了几个在线和可下载的 CSV 到 JSON,并花时间玩 OpenRefine,但无法弄清楚如何将 Station id 作为 header 然后嵌套月份,然后嵌套日期。以下是供参考的 CSV 数据示例:Station Name,Month,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
AQW00061705,1,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,824C,825C,825C,825C,825C,825C,825C,825C,825C,825C,825C,826C,826C,826C
。
每个站点 ID 都有 12 个这样的列,这使得这个过程特别困难。如果有人有使用 OpenRefine 的经验,或将这种类型的结构化数据转换为 JSON,将不胜感激。
所以在 OpenRefine 中为此编写一个导出模板有点痛苦,但可以做到。
首先在 OpenRefine 项目中使用 Station Name 列上的 'Edit Cells -> Blank Down' 菜单选项
然后转到导出并选择 "Templating"
在 'Prefix' 部分只需输入 [
在行模板部分输入:
{{if(row.record.fromRowIndex==row.index,if(row.record.fromRowIndex>0,",","")+"{\"Station Name\" :"+ jsonize(cells["Station Name"].value)+",","")}}
{{jsonize(cells["Month"].value)}}:{
{{forEach(row.columnNames[2,33],v,jsonize(v)+": "+jsonize(cells[v].value)+if(v!="31",",",""))}}
}{{if(cells["Month"].value!="12",",","")}}
{{if(row.index+1==row.record.toRowIndex,unescape("}","html"),"")}}
将行分隔符部分留空
在 'Suffix' 部分只需输入 ]
这应该会给你有效的 JSON 比如:
[
{
"Station Name": "AQW00061705",
"1": {
"1": "824C",
"2": "824C",
"3": "824C",
"4": "824C",
"5": "824C",
等等
第一个“1”是月份,后面的“1”:“824C”等是天数和读数
我必须在此处添加大量逻辑才能使其正常工作 - 理论上,我认为更简单的版本应该可以正常工作,但我看到一些奇怪的行为导致无效 JSON -因此,我已经将所有逻辑工作到模板中的 GREL 中