-2

我目前正在 ArcGIS 中的一个项目上工作,其中有一堆要素类,它们都包含一个日期字段,该字段表示要素类中的样本的采集日期。

我需要将每个要素类中的每个日期(字段类型是“日期”而不是字符串或整数)转换为一年中的某一天,然后将一年中的某一天添加​​到一个名为DOY.

日期采用mm/dd/yyyy格式,但没有前导零(7/4/15 而不是 07/04/15)。每个要素类中的示例日期字段名为或Date,但每个要素类仅包含其中一个字段。我所附的代码是我到目前为止所拥有的。Sample_DatT0_Date

注意:在这 3 种情况下,它都arcpy.calculateField_management应该与rows.updateRows上面的一致,但是当我将代码复制到这个网站时出现了我无法修复的格式问题。

编辑:每当我尝试运行此代码时,它什么都不做,也不会将一年中的日期添加到 DOY 字段中。此外,它不会给出红色 X 或绿色复选标记,而是会给出一个黄色三角形表示警告,这是因为大约 80% 的要素类已经有一个“DOY”字段,但我将 addfield_management 部分包含在开始占没有 DOY 字段的 20%。我认为通过添加 elif 语句,它不会发出警告信号,而是只会循环,直到达到相关语句。

import arcpy      
import datetime    
fcList = arcpy.ListFeatureClasses()  
for fc in fcList:    
    if "DOY" not in arcpy.ListFields(fc):    
        arcpy.AddField_management(fc,"DOY","SHORT")    
    elif "DOY" in arcpy.ListFields(fc) and "Date" in arcpy.ListFields(fc):    
        with arcpy.da.UpdateCursor(fc, "Date") as rows:    
            for row in rows:    
                rows.updateRow([datetime.datetime.strptime(row, '%m/%d/%Y')])    
            arcpy.CalculateField_management(fc,"DOY",row.timetuple().tm_yday)    
    elif "DOY" in arcpy.ListFields(fc) and "Sample_Dat" in arcpy.ListFields(fc):  
        with arcpy.da.UpdateCursor(fc,"Sample_Dat") as rows:    
            for row in rows  :  
                rows.updateRow([datetime.datetime.strptime(row, '%m/%d/%Y')])    
            arcpy.CalculateField_management(fc,"DOY",row.timetuple().tm_yday)    
    elif "DOY" in arcpy.ListFields(fc) and "T0_Date" in arcpy.ListFields(fc):     
        with arcpy.da.UpdateCursor(fc,"T0_Date") as rows:    
            for row in rows:    
                rows.updateRow([datetime.datetime.strptime(row, '%m/%d,%Y')])                              
            arcpy.CalculateField_management(fc,"DOY",row.timetuple().tm_yday)    
    else:    
        pass    
4

1 回答 1

0

根据您的评论,我认为问题在于您正在检查 DOY 是否在每种情况下都存在,而不是在需要的地方创建它并在每种情况下更新它。尝试以下操作:

编辑:我检查了文档,看起来 arcpy.ListFields() 返回一个 Field 对象,而不是一个字符串。我已经更新了我的代码。

import arcpy
import datetime

for fc in arcpy.ListFeatureClasses():
    # get fields ONCE for each FC, and only get the fields we care about
    fields = [f.name for f in arcpy.ListFields(fc) if f.name in ("DOY", "Date", "Sample_Dat", "T0_Date")]

    # add desired field if it does not exist
    if "DOY" not in fields:
        arcpy.AddField_management(fc,"DOY","SHORT")
    # otherwise, remove "DOY" from the list of fields.
    else:
        fields.pop("DOY")

    if len(fields) == 0:
        print "No DATE field for FC", fc
    else:
        # the remaining item in fields should be the other date column.
        # NOTE: this MAY HAVE UNEXPRECTED RESULTS if you can have more than one of the listed date columns in a FC.
        dtm_field = fields[0]

        # now that we've ensured that the desired "DOY" field exists, we can update it from the other date field.
        with arcpy.da.UpdateCursor(fc, dtm_field) as rows:
            count = 0
            for row in rows:
                # debugging printout so you can see progress being made
                if count % 1000 == 0:
                    print count, "rows updated"
                count += 1

                ## this assumes that all date fields have the same date pattern
                #rows.updateRow([datetime.datetime.strptime(row, '%m/%d/%Y')])
                #arcpy.CalculateField_management(fc, "DOY", row.timetuple().tm_yday)

                # do you actually need to update the datetime field? If you only need to update DOY, you can do the following:
                dtm = datetime.datetime.strptime(row, '%m/%d/%Y')
                arcpy.CalculateField_management(fc, "DOY", dtm.timetuple().tm_yday)
于 2018-08-20T19:53:09.447 回答