【问题标题】:Populate next field in table with previous data if prior field is empty如果先前字段为空,则使用先前数据填充表中的下一个字段
【发布时间】:2015-10-31 01:01:15
【问题描述】:

我有一个 CSV,它直接与我从 QGIS 2.8 开发的应用程序中的一系列点和线通信。然而,CSV 有点问题。提供 CSV 数据的硬件仅每隔几行提供一次位置数据。也就是说,有一个属性表,其中指定了 X 和 Y 列,其字段仅在关键时间填写。其余的是其他仍然有用的数据,但位置只是间歇性更新。

我的点特征结构只有最底部(最近的)属性行用于显示一个点。自然,我需要最底部行的位置数据,否则该点就会消失。目前我没有得到它,但偶尔会得到它。我的 CSV -> 点代码目前看起来像这样(使用pyshp 库):

        cur_dir = os.path.dirname(os.path.realpath(__file__))

        file_location = os.path.join(cur_dir, "data", "mycsv.csv")
        out_file = os.path.join(cur_dir, "data", "mypoint.shp")
        idd, az, y, x = [], [], [], []

        with open(file_location, 'rb') as csvfile:
            r = list(csv.reader(csvfile, delimiter=','))
            reader = r[len(r) - 1:] #read only top row
            for i, row in reversed(list(enumerate(reader))): #reverse table
                idd.append(str(row[0]))
                az.append(float(row[2]))
                y.append(float(row[6]))
                x.append(float(row[7]))
                print "appended"


        w = shapefile.Writer(shapefile.POINT)
        w.field('ID', 'N')
        w.field('AZIMUTH', 'N', 12)
        w.field('Y', 'F', 10, 8)
        w.field('X', 'F', 10, 8)

        for j, k in enumerate(x): #write shapefile
            w.point(k, y[j])
            w.record(idd[j],az[j],y[j], k )
            print "recorded"

        w.save(out_file)

这是 CSV 的 sn-p。您将在右侧看到切碎的列:http://i.stack.imgur.com/ULZOS.png

我已经开始尝试在多个枚举器下方的各个位置添加if x > 0: 条件,以在读取数据之前可能会停止数字化,但我每次都会收到错误min() arg is an empty sequence。我什至不确定这是开始的正确位置,因为它可能只是将属性彼此不按顺序排列。我真的只需要某种 “如果 X 或 Y 字段为空,则使用先前字段的数据填充字段”脚本。

我正在使用 Python 2.7 和 PyQt4,从 QGIS 2.8 API 开发,并在 Ubuntu 14.04 上运行,

【问题讨论】:

    标签: python csv pyqt4 qgis


    【解决方案1】:

    您可以缓存 X 和 Y 数据点的最后一个有效值,我假设它们在 row[6] 和 row[7] 中

        with open(file_location, 'rb') as csvfile:
            r = list(csv.reader(csvfile, delimiter=','))
            reader = r[len(r) - 1:] #read only top row
            lastX = 0.
            lastY = 0.
            for i, row in reversed(list(enumerate(reader))): #reverse table
                idd.append(str(row[0]))
                az.append(float(row[2]))
                try:
                    y.append(float(row[6]))
                    lastY = float(row[6]))
                except (TypeError, ValueError) as e:
                    if len(y) > 0:
                        y.append(lastY)
    
                try:
                    x.append(float(row[7]))
                    lastX = float(row[7]))
                except (TypeError, ValueError) as e:
                    if len(x) > 0:
                        x.append(lastX)
    
                print "appended"
    

    我假设缺少的 CSV 值以空字符串或无的形式出现。当转换为 float() 时,这两个值都会引发异常。如果值是 0,则要求原始开发人员将值设为空,因为 0 可能是真实坐标而不是缺失坐标。

    如果 X 和 Y 总是同时出现(如果你有一个,你总是有另一个),那么你可以使用单个 try/except 块来处理所有情况。

    【讨论】:

    • 奇怪的是,当注意到空字段时,它会抛出ERROR 1: Error in fread() reading object of size 28 at offset 100 from .shp file。知道可能是什么原因造成的吗?我稍微调整了一下并将ifs 设置为if len(x) == 0: 以查看lastX/lastY 变量是否没有任何内容,虽然错误消失了,但坐标每次都是0,0。每次脚本运行时,对 lastX/lastY 的追加是否会恢复为 0?
    • 尝试同时删除 if 语句。我试图通过不附加任何内容来删除初始错误值,除非已经找到有效值。
    • 所以,不管 if 语句如何,我认为还有其他问题正在发生,因为我几乎可以肯定我已将代码设置为正确缓存,但无论何时运行,我都会明白ERROR 1: Error in fread() reading object of size 28 at offset 100 from .shp file 每次都出错。当lastXlastY 变量设置为0. 时,坐标默认为0,0,就像您写的那样,或者当它们设置为[] 时会引发上述错误。我的直觉是,将它们设置为 [] 是正确的做法,但我从未遇到过这个 fread() 函数错误,而是抛出了。
    • 我想通了。我删除了 if 语句,并在代码开头添加了 lastXlastY 类属性。我最好的猜测是,当它们是局部变量时,它们最初从未缓存过。如果字段为空,try 将跳到except,因此无论如何都会附加0。感谢您为我指明正确的方向!
    猜你喜欢
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多