【问题标题】:Python - using AND in an IF to reference 2 variablesPython - 在 IF 中使用 AND 来引用 2 个变量
【发布时间】:2021-06-22 11:15:26
【问题描述】:

我正在尝试使用模块 pyproj 编写一个 python 函数,它将基于两个因素进行坐标转换 - 文件名的结尾和 2 行的名称。

例如:if self.file_crs == 'IG' 如果文件结尾是 IG 代表爱尔兰网格

for idx,el in enumerate(row):
  if keys[idx].capitalize() in ['Easting', 'Northing']:

如果这两列分别称为Easting 和Northing

然后运行

inProj = Proj(init='epsg:29903') # Irish Grid
outProj = Proj(init='epsg:4326') # WGS84
x1, y1 = row[1], row[2]  # easting, northing
x2, y2 = transform(inProj, outProj, x1, y1)
row[1], row[2] = y2, x2

我怎样才能将这些组合起来看起来像:

if self.file_crs == 'IG' and keys[idx].capitalize() in ['Easting', 'Northing']:
  inProj = Proj(init='epsg:29903') # Irish Grid
  outProj = Proj(init='epsg:4326') # WGS84
  x1, y1 = row[1], row[2]  # easting, northing
  x2, y2 = transform(inProj, outProj, x1, y1)
  row[1], row[2] = y2, x2

我需要能够事先引用 idx,以便在我的“if”语句中识别它

编辑

keys 是正在解析的 csv 中的行名。

if line_count == 0:
                    keys = row

行如下

Name Easting Northing Time
Test1 169973 77712 01/01/2020 09:51:03 AM

【问题讨论】:

  • keysrow 是什么?
  • @quamrana 抱歉,请参阅已编辑的问题!
  • 您的意思是keys 是列名,row 是一次一行吗?你能举个例子吗?
  • @quamrana 完全正确!是的,我已经包含了一个行的例子
  • 首先我会说你应该检查line_count == 0时的列名,如果它们不是你所期望的则抛出异常。这将消除其中一种复杂性。

标签: python python-3.x if-statement pyproj


【解决方案1】:

好的,我在临时测试工具中尝试了这个,它运行了:

class TestPositions:
    def __init__(self, crs):
        self.file_crs = crs

    def process_incoming_file(self, bucket, key, event):
        if self.file_crs == 'BNG':
            inProj = Proj(init="epsg:27700")  # British National Grid
            outProj = Proj(init="epsg:4326")  # WGS84
        else:
            inProj = Proj(init='epsg:29903')  # Irish Grid
            outProj = Proj(init='epsg:4326')  # WGS84

        try:

            decoded_content = ['Name|Easting|Northing|Time', 'Test1|169973|77712|01/01/2020 09:51:03 AM']
            print('processing data')
            rows = csv.reader(decoded_content, delimiter='|')
            for line_count, row in enumerate(rows):
                if line_count == 0:
                    keys = [title.lower() for title in row]
                    print('keys', keys)
                    isEasting = ('easting' in keys)
                else:
                    json_doc = {}
                    for idx, el in enumerate(row):
                        if keys[idx] in ['time', 'date serviced', 'timestamp']:
                            timestamp = self.format_timestring(el)
                        else:
                            json_doc[keys[idx]] = el

                    if isEasting:
                        json_doc['easting'], json_doc['northing'] = transform(inProj, outProj, json_doc['easting'], json_doc['northing'])
                        json_doc['latitude'] = json_doc.pop('easting')
                        json_doc['longitude'] = json_doc.pop('northing')
                    geom = Point(json_doc['Longitude'], json_doc['Latitude'])
                    WKB_format = wkb.dumps(geom, hex=True, srid=4326)

                    fid = uuid.uuid4()  # assign new UUID to each row

                    print(json_doc['name'])
                    print(fid)
                    print(timestamp)
                    print(WKB_format)
                    print(json_doc)

        except Exception as e:
            print(f'Exception: {e.__class__.__name__}({e})')

您可以在方法的开头看到我是如何生成 inProjoutProj 的,因此每次调用 process_incoming_file() 时都会生成一次。

我已经硬编码了decoded_content。您将需要您的原件:

            response = self.client.get_object(Bucket=bucket, Key=key)
            decoded_content = response['Body'].read().decode('utf-8')
            print(decoded_content)

            rows = csv.reader(decoded_content.splitlines(), delimiter=',')
            # no need to convert to a list

您会注意到,我检查了第一行的列名并抛出了异常,因为继续缺少信息将毫无意义。

另外,一旦我将单元格复制到json_doc,就无需在循环中再次引用row

更新:

我添加了对 'easting' 的检查,作为将出现一组列名的代理。所以,if isEasting: 进行转换,否则假定不需要转换。

【讨论】:

  • 如果我尝试这种方法,我似乎收到了错误invalid syntax (<fstring>, line 1)。我使用python 3.6作为参考
  • 好的,试试这条线:raise RuntimeError(f'keys={keys} not valid')
  • 是的,谢谢!还有一个问题 - 请参阅以下行 if ('easting' not in keys) or ('northing' not in keys): raise RuntimeError(f'{keys=} not valid') 列标题可以是东向和北向或经度和纬度 - 我需要它的功能来识别它的 eastingnorthing 然后执行 inProj 和 @987654337 @,否则,如果是 longitudelatitude,则保持原样。
  • 好的,如果标题都不是对的,或者它那么可能是一个或另一个不值得检查?
  • 标题将始终为eastingnorthinglongitudelatitude。仅当标题为easting and northing 格式时才需要进行坐标转换
【解决方案2】:

回复上面的回答

    def process_incoming_file(self, bucket, key, event):
        if self.file_crs == 'BNG':
            inProj = Proj(init="epsg:27700")  # British National Grid
            outProj = Proj(init="epsg:4326")  # WGS84
        else:
            inProj = Proj(init='epsg:29903')  # Irish Grid
            outProj = Proj(init='epsg:4326')  # WGS84

        try:
            response = self.client.get_object(Bucket=bucket, Key=key)
            decoded_content = response['Body'].read().decode('utf-8')
            print(decoded_content)
            print('processing data')
            rows = csv.reader(decoded_content.splitlines(), delimiter=',')
            for line_count, row in enumerate(rows):
                if line_count == 0:
                    keys = [title.lower() for title in row]
                    print('keys', keys)
                    isEasting = ('easting' in keys)
                else:
                    json_doc = {}
                    for idx, el in enumerate(row):
                        if keys[idx] in ['time', 'date serviced', 'timestamp']:
                            timestamp = self.format_timestring(el)
                        else:
                            json_doc[keys[idx]] = el

                    if isEasting:
                        json_doc['easting'], json_doc['northing'] = transform(inProj, outProj, json_doc['easting'], json_doc['northing'])
                        json_doc['latitude'] = json_doc.pop('easting')
                        json_doc['longitude'] = json_doc.pop('northing')
                    geom = Point(json_doc['longitude'], json_doc['latitude'])
                    WKB_format = wkb.dumps(geom, hex=True, srid=4326)

                    fid = uuid.uuid4()  # assign new UUID to each row

                    print(json_doc['name'])
                    print(fid)
                    print(timestamp)
                    print(WKB_format)
                    print(json_doc)

        except Exception as e:
            print(f'Exception: {e.__class__.__name__}({e})')

【讨论】:

  • 您可能需要暂时删除 try:except: 以获得错误回溯,以便能够准确判断数字而非字符串的错误来自何处。
  • 我浏览了代码,它是geom = Point(json_doc['longitude'], json_doc['latitude']) WKB_format = wkb.dumps(geom, hex=True, srid=4326),它抛出了错误TypeError(must be real number, not str)。这发生在我的原始代码中,直到我添加了line_count += 1
  • 如果您有:geom = Point(int(json_doc['longitude']), int(json_doc['latitude']))geom = Point(float(json_doc['longitude']), float(json_doc['latitude'])),会发生什么?
  • 第一个给我这个错误ValueError(invalid literal for int() with base 10: '-8.6077881')
  • 第二个完美!!!!最后 - 谢谢!!!!
猜你喜欢
  • 2013-04-03
  • 2022-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多