【问题标题】:Use Pandas dataframe and groupby to properly format coordinates into JSON bbox bounds list使用 Pandas 数据框和 groupby 将坐标正确格式化为 JSON bbox 边界列表
【发布时间】:2021-03-06 12:29:31
【问题描述】:

我正在尝试获取 json_string 中的坐标以正确显示在输出 JSON 文件的 "bbox": "bounds":[] 列表中,如下所示:

    "bbox": {
      "crs": "EPSG:4326",
      "bounds": [
        -85.313409,
        35.045113,
        -85.309768,
        35.046858
      ]
    }

目标是为数据框中的每条记录输出一组边界,如json_string 中指定的那样。到目前为止,这是我的代码:

import pandas as pd
import json

json_string = '[{"grp1":"aaa","grp2":"streets","name":"Carter","minx":-85.318334,"miny":35.034634,"maxx":-85.310419,"maxy":35.046181},{"grp1":"aaa","grp2":"streets","name":"Chestnut","minx":-85.313269,"miny":35.045157,"maxx":-85.309903,"maxy":35.046796},{"grp1":"aaa","grp2":"streets","name":"Main","minx":-85.319367,"miny":35.037966,"maxx":-85.314929,"maxy":35.041614},{"grp1":"aaa","grp2":"aaa","name":"aaa","minx":-85.318072,"miny":35.041225,"maxx":-85.312745,"maxy":35.04619},{"grp1":"aaa","grp2":"ramps","name":"Ramp_A","minx":-85.321187,"miny":35.033812,"maxx":-85.316961,"maxy":35.037435},{"grp1":"aaa","grp2":"ramps","name":"Ramp_B","minx":-85.321281,"miny":35.032167,"maxx":-85.31736,"maxy":35.037439},{"grp1":"aaa","grp2":"ramps","name":"Ramp_C","minx":-85.321833,"miny":35.031563,"maxx":-85.317803,"maxy":35.034746},{"grp1":"test1","grp2":"test2","name":"testname","minx":-85.317081,"miny":35.043565,"maxx":-85.313016,"maxy":35.048088}]'

a_json = json.loads(json_string)

df = pd.DataFrame(a_json)

SCALES = [250000, 100000, 50000, 25000, 10000, 5000, 2500, 1000, 500, 250]
AVAILFORMS = ['image/jpeg', 'image/png', 'image/png; mode=16bit', 'image/png; mode=8bit', 'image/png; mode=1bit', 'application/dxf']
INFOFORMS = ['text/plain', 'text/html', 'text/xml', 'application/vnd.ogc.gml', 'application/vnd.ogc.gml/3.1.1', 'application/json', 'application/geo+json']
BBOX = {'crs': 'EPSG:4326', 'bounds': [df['minx'], df['miny'], df['maxx'], df['maxy']]}
INITBBOX = {'crs': 'EPSG:4326', 'bounds': [-85.313409, 35.045113, -85.309768, 35.046858]}

df['title'] = df['grp1'] + '-' + df['grp2']
df['id'] = df['grp1'] + '-' + df['grp2'] + '-' + df['name'] + '.qgs'
df['description'] = ''
df['availableFormats'] = pd.Series(dtype=object)
df['availableFormats'] = df['availableFormats'].apply(lambda x: AVAILFORMS)
df['version'] = '1.3.0'
df['infoFormats'] = pd.Series(dtype=object)
df['infoFormats'] = df['infoFormats'].apply(lambda x: INFOFORMS)

df['lowerLeftX'] = df['minx']
df['lowerLeftY'] = df['miny']
df['upperRightX'] = df['maxx']
df['upperRightY'] = df['maxy']

df['bbox'] = pd.Series(dtype=object)
df['bbox'] = df['bbox'].apply(lambda x: BBOX)

df['initialBbox'] = pd.Series(dtype=object)
df['initialBbox'] = df['initialBbox'].apply(lambda x: INITBBOX)

df['scales'] = pd.Series(dtype=object)
df['scales'] = df['scales'].apply(lambda x: SCALES)

result_json = df[['title', 'name', 'id', 'description', 'availableFormats', 'version', 'infoFormats', 'lowerLeftX', 'lowerLeftY', 'upperRightX', 'upperRightY', 'bbox', 'initialBbox', 'scales']].groupby(['title'])\
    .apply(lambda x: x[['name', 'id', 'description', 'availableFormats', 'version', 'infoFormats', 'lowerLeftX', 'lowerLeftY', 'upperRightX', 'upperRightY', 'bbox', 'initialBbox', 'scales']].rename(columns={'name': 'title'}).to_dict('r'))\
    .reset_index()\
    .rename(columns={0:'items'})\
    .to_json(orient='records')

themes = {}
themes['title'] = 'root'
themes['subdirs'] = json.loads(result_json)

parent = {'themes': themes}

with open('output.json', 'w') as f:
    j = json.dump(parent, f, indent=2)

output.json 当前如下所示:

{
  "themes": {
    "title": "root",
    "subdirs": [
      {
        "title": "aaa-aaa",
        "items": [
          {
            "title": "aaa",
            "id": "aaa-aaa-aaa.qgs",
            "description": "",
            "availableFormats": [
              "image/jpeg",
              "image/png",
              "image/png; mode=16bit",
              "image/png; mode=8bit",
              "image/png; mode=1bit",
              "application/dxf"
            ],
            "version": "1.3.0",
            "infoFormats": [
              "text/plain",
              "text/html",
              "text/xml",
              "application/vnd.ogc.gml",
              "application/vnd.ogc.gml/3.1.1",
              "application/json",
              "application/geo+json"
            ],
            "lowerLeftX": -85.318072,
            "lowerLeftY": 35.041225,
            "upperRightX": -85.312745,
            "upperRightY": 35.04619,
            "bbox": {
              "crs": "EPSG:4326",
              "bounds": [
                [
                  -85.318334,
                  -85.313269,
                  -85.319367,
                  -85.318072,
                  -85.321187,
                  -85.321281,
                  -85.321833,
                  -85.317081
                ],
                [
                  35.034634,
                  35.045157,
                  35.037966,
                  35.041225,
                  35.033812,
                  35.032167,
                  35.031563,
                  35.043565
                ],
                [
                  -85.310419,
                  -85.309903,
                  -85.314929,
                  -85.312745,
                  -85.316961,
                  -85.31736,
                  -85.317803,
                  -85.313016
                ],
                [
                  35.046181,
                  35.046796,
                  35.041614,
                  35.04619,
                  35.037435,
                  35.037439,
                  35.034746,
                  35.048088
                ]
              ]
            },
            "initialBbox": {
              "crs": "EPSG:4326",
              "bounds": [
                -85.313409,
                35.045113,
                -85.309768,
                35.046858
              ]
            },
            "scales": [
              250000,
              100000,
              50000,
              25000,
              10000,
              5000,
              2500,
              1000,
              500,
              250
            ]
          }
        ]
      },
      {
        "title": "aaa-ramps",
        "items": [
          {
            "title": "Ramp_A",
            "id": "aaa-ramps-Ramp_A.qgs",
            "description": "",
            "availableFormats": [
              "image/jpeg",
              "image/png",
              "image/png; mode=16bit",
              "image/png; mode=8bit",
              "image/png; mode=1bit",
              "application/dxf"
            ],
            "version": "1.3.0",
            "infoFormats": [
              "text/plain",
              "text/html",
              "text/xml",
              "application/vnd.ogc.gml",
              "application/vnd.ogc.gml/3.1.1",
              "application/json",
              "application/geo+json"
            ],
            "lowerLeftX": -85.321187,
            "lowerLeftY": 35.033812,
            "upperRightX": -85.316961,
            "upperRightY": 35.037435,
            "bbox": {
              "crs": "EPSG:4326",
              "bounds": [
                [
                  -85.318334,
                  -85.313269,
                  -85.319367,
                  -85.318072,
                  -85.321187,
                  -85.321281,
                  -85.321833,
                  -85.317081
                ],
                [
                  35.034634,
                  35.045157,
                  35.037966,
                  35.041225,
                  35.033812,
                  35.032167,
                  35.031563,
                  35.043565
                ],
                [
                  -85.310419,
                  -85.309903,
                  -85.314929,
                  -85.312745,
                  -85.316961,
                  -85.31736,
                  -85.317803,
                  -85.313016
                ],
                [
                  35.046181,
                  35.046796,
                  35.041614,
                  35.04619,
                  35.037435,
                  35.037439,
                  35.034746,
                  35.048088
                ]
              ]
            },
            "initialBbox": {
              "crs": "EPSG:4326",
              "bounds": [
                -85.313409,
                35.045113,
                -85.309768,
                35.046858
              ]
            },
            "scales": [
              250000,
              100000,
              50000,
              25000,
              10000,
              5000,
              2500,
              1000,
              500,
              250
            ]
          },
          {
            "title": "Ramp_B",
            "id": "aaa-ramps-Ramp_B.qgs",
            "description": "",
            "availableFormats": [
              "image/jpeg",
              "image/png",
              "image/png; mode=16bit",
              "image/png; mode=8bit",
              "image/png; mode=1bit",
              "application/dxf"
            ],
            "version": "1.3.0",
            "infoFormats": [
              "text/plain",
              "text/html",
              "text/xml",
              "application/vnd.ogc.gml",
              "application/vnd.ogc.gml/3.1.1",
              "application/json",
              "application/geo+json"
            ],
            "lowerLeftX": -85.321281,
            "lowerLeftY": 35.032167,
            "upperRightX": -85.31736,
            "upperRightY": 35.037439,
            "bbox": {
              "crs": "EPSG:4326",
              "bounds": [
                [
                  -85.318334,
                  -85.313269,
                  -85.319367,
                  -85.318072,
                  -85.321187,
                  -85.321281,
                  -85.321833,
                  -85.317081
                ],
                [
                  35.034634,
                  35.045157,
                  35.037966,
                  35.041225,
                  35.033812,
                  35.032167,
                  35.031563,
                  35.043565
                ],
                [
                  -85.310419,
                  -85.309903,
                  -85.314929,
                  -85.312745,
                  -85.316961,
                  -85.31736,
                  -85.317803,
                  -85.313016
                ],
                [
                  35.046181,
                  35.046796,
                  35.041614,
                  35.04619,
                  35.037435,
                  35.037439,
                  35.034746,
                  35.048088
                ]
              ]
            },
            "initialBbox": {
              "crs": "EPSG:4326",
              "bounds": [
                -85.313409,
                35.045113,
                -85.309768,
                35.046858
              ]
            },
            "scales": [
              250000,
              100000,
              50000,
              25000,
              10000,
              5000,
              2500,
              1000,
              500,
              250
            ]
          },
          {
            "title": "Ramp_C",
            "id": "aaa-ramps-Ramp_C.qgs",
            "description": "",
            "availableFormats": [
              "image/jpeg",
              "image/png",
              "image/png; mode=16bit",
              "image/png; mode=8bit",
              "image/png; mode=1bit",
              "application/dxf"
            ],
            "version": "1.3.0",
            "infoFormats": [
              "text/plain",
              "text/html",
              "text/xml",
              "application/vnd.ogc.gml",
              "application/vnd.ogc.gml/3.1.1",
              "application/json",
              "application/geo+json"
            ],
            "lowerLeftX": -85.321833,
            "lowerLeftY": 35.031563,
            "upperRightX": -85.317803,
            "upperRightY": 35.034746,
            "bbox": {
              "crs": "EPSG:4326",
              "bounds": [
                [
                  -85.318334,
                  -85.313269,
                  -85.319367,
                  -85.318072,
                  -85.321187,
                  -85.321281,
                  -85.321833,
                  -85.317081
                ],
                [
                  35.034634,
                  35.045157,
                  35.037966,
                  35.041225,
                  35.033812,
                  35.032167,
                  35.031563,
                  35.043565
                ],
                [
                  -85.310419,
                  -85.309903,
                  -85.314929,
                  -85.312745,
                  -85.316961,
                  -85.31736,
                  -85.317803,
                  -85.313016
                ],
                [
                  35.046181,
                  35.046796,
                  35.041614,
                  35.04619,
                  35.037435,
                  35.037439,
                  35.034746,
                  35.048088
                ]
              ]
            },
            "initialBbox": {
              "crs": "EPSG:4326",
              "bounds": [
                -85.313409,
                35.045113,
                -85.309768,
                35.046858
              ]
            },
            "scales": [
              250000,
              100000,
              50000,
              25000,
              10000,
              5000,
              2500,
              1000,
              500,
              250
            ]
          }
        ]
      },
      {
        "title": "aaa-streets",
        "items": [
          {
            "title": "Carter",
            "id": "aaa-streets-Carter.qgs",
            "description": "",
            "availableFormats": [
              "image/jpeg",
              "image/png",
              "image/png; mode=16bit",
              "image/png; mode=8bit",
              "image/png; mode=1bit",
              "application/dxf"
            ],
            "version": "1.3.0",
            "infoFormats": [
              "text/plain",
              "text/html",
              "text/xml",
              "application/vnd.ogc.gml",
              "application/vnd.ogc.gml/3.1.1",
              "application/json",
              "application/geo+json"
            ],
            "lowerLeftX": -85.318334,
            "lowerLeftY": 35.034634,
            "upperRightX": -85.310419,
            "upperRightY": 35.046181,
            "bbox": {
              "crs": "EPSG:4326",
              "bounds": [
                [
                  -85.318334,
                  -85.313269,
                  -85.319367,
                  -85.318072,
                  -85.321187,
                  -85.321281,
                  -85.321833,
                  -85.317081
                ],
                [
                  35.034634,
                  35.045157,
                  35.037966,
                  35.041225,
                  35.033812,
                  35.032167,
                  35.031563,
                  35.043565
                ],
                [
                  -85.310419,
                  -85.309903,
                  -85.314929,
                  -85.312745,
                  -85.316961,
                  -85.31736,
                  -85.317803,
                  -85.313016
                ],
                [
                  35.046181,
                  35.046796,
                  35.041614,
                  35.04619,
                  35.037435,
                  35.037439,
                  35.034746,
                  35.048088
                ]
              ]
            },
            "initialBbox": {
              "crs": "EPSG:4326",
              "bounds": [
                -85.313409,
                35.045113,
                -85.309768,
                35.046858
              ]
            },
            "scales": [
              250000,
              100000,
              50000,
              25000,
              10000,
              5000,
              2500,
              1000,
              500,
              250
            ]
          },
          {
            "title": "Chestnut",
            "id": "aaa-streets-Chestnut.qgs",
            "description": "",
            "availableFormats": [
              "image/jpeg",
              "image/png",
              "image/png; mode=16bit",
              "image/png; mode=8bit",
              "image/png; mode=1bit",
              "application/dxf"
            ],
            "version": "1.3.0",
            "infoFormats": [
              "text/plain",
              "text/html",
              "text/xml",
              "application/vnd.ogc.gml",
              "application/vnd.ogc.gml/3.1.1",
              "application/json",
              "application/geo+json"
            ],
            "lowerLeftX": -85.313269,
            "lowerLeftY": 35.045157,
            "upperRightX": -85.309903,
            "upperRightY": 35.046796,
            "bbox": {
              "crs": "EPSG:4326",
              "bounds": [
                [
                  -85.318334,
                  -85.313269,
                  -85.319367,
                  -85.318072,
                  -85.321187,
                  -85.321281,
                  -85.321833,
                  -85.317081
                ],
                [
                  35.034634,
                  35.045157,
                  35.037966,
                  35.041225,
                  35.033812,
                  35.032167,
                  35.031563,
                  35.043565
                ],
                [
                  -85.310419,
                  -85.309903,
                  -85.314929,
                  -85.312745,
                  -85.316961,
                  -85.31736,
                  -85.317803,
                  -85.313016
                ],
                [
                  35.046181,
                  35.046796,
                  35.041614,
                  35.04619,
                  35.037435,
                  35.037439,
                  35.034746,
                  35.048088
                ]
              ]
            },
            "initialBbox": {
              "crs": "EPSG:4326",
              "bounds": [
                -85.313409,
                35.045113,
                -85.309768,
                35.046858
              ]
            },
            "scales": [
              250000,
              100000,
              50000,
              25000,
              10000,
              5000,
              2500,
              1000,
              500,
              250
            ]
          },
          {
            "title": "Main",
            "id": "aaa-streets-Main.qgs",
            "description": "",
            "availableFormats": [
              "image/jpeg",
              "image/png",
              "image/png; mode=16bit",
              "image/png; mode=8bit",
              "image/png; mode=1bit",
              "application/dxf"
            ],
            "version": "1.3.0",
            "infoFormats": [
              "text/plain",
              "text/html",
              "text/xml",
              "application/vnd.ogc.gml",
              "application/vnd.ogc.gml/3.1.1",
              "application/json",
              "application/geo+json"
            ],
            "lowerLeftX": -85.319367,
            "lowerLeftY": 35.037966,
            "upperRightX": -85.314929,
            "upperRightY": 35.041614,
            "bbox": {
              "crs": "EPSG:4326",
              "bounds": [
                [
                  -85.318334,
                  -85.313269,
                  -85.319367,
                  -85.318072,
                  -85.321187,
                  -85.321281,
                  -85.321833,
                  -85.317081
                ],
                [
                  35.034634,
                  35.045157,
                  35.037966,
                  35.041225,
                  35.033812,
                  35.032167,
                  35.031563,
                  35.043565
                ],
                [
                  -85.310419,
                  -85.309903,
                  -85.314929,
                  -85.312745,
                  -85.316961,
                  -85.31736,
                  -85.317803,
                  -85.313016
                ],
                [
                  35.046181,
                  35.046796,
                  35.041614,
                  35.04619,
                  35.037435,
                  35.037439,
                  35.034746,
                  35.048088
                ]
              ]
            },
            "initialBbox": {
              "crs": "EPSG:4326",
              "bounds": [
                -85.313409,
                35.045113,
                -85.309768,
                35.046858
              ]
            },
            "scales": [
              250000,
              100000,
              50000,
              25000,
              10000,
              5000,
              2500,
              1000,
              500,
              250
            ]
          }
        ]
      },
      {
        "title": "test1-test2",
        "items": [
          {
            "title": "testname",
            "id": "test1-test2-testname.qgs",
            "description": "",
            "availableFormats": [
              "image/jpeg",
              "image/png",
              "image/png; mode=16bit",
              "image/png; mode=8bit",
              "image/png; mode=1bit",
              "application/dxf"
            ],
            "version": "1.3.0",
            "infoFormats": [
              "text/plain",
              "text/html",
              "text/xml",
              "application/vnd.ogc.gml",
              "application/vnd.ogc.gml/3.1.1",
              "application/json",
              "application/geo+json"
            ],
            "lowerLeftX": -85.317081,
            "lowerLeftY": 35.043565,
            "upperRightX": -85.313016,
            "upperRightY": 35.048088,
            "bbox": {
              "crs": "EPSG:4326",
              "bounds": [
                [
                  -85.318334,
                  -85.313269,
                  -85.319367,
                  -85.318072,
                  -85.321187,
                  -85.321281,
                  -85.321833,
                  -85.317081
                ],
                [
                  35.034634,
                  35.045157,
                  35.037966,
                  35.041225,
                  35.033812,
                  35.032167,
                  35.031563,
                  35.043565
                ],
                [
                  -85.310419,
                  -85.309903,
                  -85.314929,
                  -85.312745,
                  -85.316961,
                  -85.31736,
                  -85.317803,
                  -85.313016
                ],
                [
                  35.046181,
                  35.046796,
                  35.041614,
                  35.04619,
                  35.037435,
                  35.037439,
                  35.034746,
                  35.048088
                ]
              ]
            },
            "initialBbox": {
              "crs": "EPSG:4326",
              "bounds": [
                -85.313409,
                35.045113,
                -85.309768,
                35.046858
              ]
            },
            "scales": [
              250000,
              100000,
              50000,
              25000,
              10000,
              5000,
              2500,
              1000,
              500,
              250
            ]
          }
        ]
      }
    ]
  }
}

添加:

我希望它显示数据框中每一行的 X 和 Y 坐标,而不是 X 和 Y 坐标的集合(列表)的最大值或最小值。

换句话说,我希望它显示相同的 X 和 Y 坐标

df['lowerLeftX'] = df['minx']
df['lowerLeftY'] = df['miny']
df['upperRightX'] = df['maxx']
df['upperRightY'] = df['maxy']

但将这些坐标放在"bbox": "bounds": 中,如下所示:

"bbox": "bounds": [['minx'], ['miny'], ['maxx'], ['maxy']]

【问题讨论】:

    标签: python json pandas list pandas-groupby


    【解决方案1】:

    要为每一行唯一地为bbox 构建dict

    完全删除常量BBOX,除非您在某些时候需要整个数据集的溶解边界框。

    为每一行构建一个bbox

    df['bbox'] = pd.Series(dtype=object)
    df['bbox'] = df.apply(lambda row: {'crs': "EPSG:4326", 
            'bounds': [row.minx, row.miny, row.maxx, row.maxy] }, axis = 1 )
    

    axis =1 告诉apply 放弃rows,而不是columns。每行都作为series 传递给lambda。请注意,我使用的是点表示法row.minx,在这种情况下与row['minx'] 相同,但要简洁。

    【讨论】:

    • 感谢您抽出宝贵时间回答。我在原始帖子中添加了一些附加信息以进行澄清。
    • 感谢@NateB,准备阅读如何在 Pandas 中使用 lambda。对我来说都是希腊语。
    猜你喜欢
    • 2021-09-27
    • 2019-12-05
    • 2021-01-13
    • 1970-01-01
    • 2021-09-03
    • 2021-12-06
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多