首页 > 解决方案 > 在 for 循环中一次创建多个数据帧

问题描述

我有一个脚本可以检查 GIS 数据库中的特征是否存在字段中的缺失值。如果缺少该值,则会将其附加到数据框中,其中顶列是特征的名称。理想情况下,我想将其拆分,以便功能名称成为工作表名称,但我不确定如何迭代地执行此操作。需要注意的是,不是每个特征都会有缺失值,不同时间的不同特征可能有也可能没有缺失值,这就是做这个检查的重点。

df = pd.DataFrame()

for dst, dstkey in zip(Dst, DstKey):
    with arcpy.da.SearchCursor(dst, ("OBJECTID", dstkey)) as cursor:
        #returns an iterator of tuples
        for row in cursor:
            if (row[1] is None or not str(row[1]).strip()):
                df = df.append(pd.DataFrame({dst.split("\\").pop(): str(row[0])}, index=[0]), ignore_index=True)

这将返回一个数据框。理想情况下,我希望将多个数据框dstsheet_name. 这里的问题是我不知道有多少(如果有的话)特征将具有空值。

我尝试为每个功能创建一个空白数据框,但我无法弄清楚在上面的代码块中如何使用它。

d = {dst.split("\\").pop().split(".")[2]: pd.DataFrame() for dst in Dst}

值得注意的是,这Dst是一个 SQL 数据库的路径列表,并且DstKey是我正在检查的每个数据库中的一个字段。

标签: pythonpython-3.xpandasdataframe

解决方案


考虑使用以dst作为键的数据帧字典,构建在循环外连接的数据帧内部列表:

df_dict = {}

for dst, dstkey in zip(Dst, DstKey):
    inner = []
    with arcpy.da.SearchCursor(dst, ("OBJECTID", dstkey)) as cursor:
        # returns an iterator of tuples
        for row in cursor:
            if (row[1] is None or not str(row[1]).strip()):
                inner.append(pd.DataFrame({dst.split("\\").pop(): str(row[0])}, index=[0])

    df_dict[dstkey] = pd.concat(inner, ignore_index=True)

或者使用列表理解:

df_dict = {}

for dst, dstkey in zip(Dst, DstKey):
    with arcpy.da.SearchCursor(dst, ("OBJECTID", dstkey)) as cursor:
        # returns an iterator of tuples
        inner = [pd.DataFrame({dst.split("\\").pop(): str(row[0])}, index=[0]) 
                 for row in cursor if (row[1] is None or not str(row[1]).strip())]

    df_dict[dstkey] = pd.concat(inner, ignore_index=True)

对于使用数据框字典的 Excel 导出:

writer = pd.ExcelWriter('/path/to/output.xlsx')

for i, df in df_dict.items():
   df.to_excel(writer, sheet_name=i)

writer.save()

推荐阅读