用Python自动计算几个表的值,包括过滤

发布于 2025-02-07 09:11:20 字数 3315 浏览 2 评论 0 原文

我需要编写一个Python脚本来通过组合几个表(如果可能的话,在Arcmap 10.7中使用Arcpy)自动计算成本,但是我很难做到这一点,因为我从未真正做过这样的事情。 因此,我在这里,希望这个社区中的某种善良的灵魂能够帮助我。 我的表有几列,但我刚刚列出了与我的计算相关的onces,为简单起见,将表格为table1,table2,table3。不幸的是,我没有任何可以在此处发布的虚拟数据……

我的表格:

  • table1,列:区域(int),number(string),code(int),e节(字符串)
  • table2,列:代码(int) ,a_value(double)
  • 表3,列:number(string),b _value(double),cost_calc(double)

table1和table2是通过相应列中的ID连接的«代码» ; Table1和Table3是通过相应列中的数字«数字»

存储在3个不同表中的值中的值自动计算成本...

目标:脚本应自动从 结果看起来像):

步骤1:在表1中过滤,从列«章节»所有行都带有 值«b»(仅需要具有此值的那些行才能进一步 计算,不应包括其他行)

步骤2:在«a_value»(table2)中乘以所有值 «区域»(table1)(对于第1步中过滤的所有行 - 当然,步骤1和步骤2如果更容易(不确定)) - 可以将interim结果写入临时表或将Table1中的新列 - 任何更容易的…

步骤3:总结步骤2中根据其数字计算的结果(Table1)(在这里,我希望所有计算的结果根据其数字组合/汇总 - 计算后,有5个数字的结果。 12345(因为它们的«代码»不同),并且应该汇总到临时结果中,可以写入table3

中的临时表或新列。

示例 中平均值“根据数字汇总计算的临时结果(COST_INTERIM)”,这就是应该发生的事情: 计算后表2 table> table总结步骤3

步骤4:在步骤3中计算的结果(汇总值)应乘以“ b_value”列中的值。此步骤的结果也将是最终结果,因此写入列«cost_calc»(table3)

我知道我可以使用searchcursor(arcpy)函数执行第一步,但除此之外,我迷路了。 。 因此,除了导入Arcpy,数学等,并设置环境,并首先尝试使用搜索手机功能

我的第一次尝试:

fc="table1" fields = ['section','area'] delimfield = arcpy.AddFieldDelimiters(fc, fields[1]) cursor = arcpy.da.SearchCursor(fc, fields, delimfield +"= 'B'")

#Open a searchcursor
rows = arcpy.SearchCursor("c:/Users/myuser/mydatabase/table1",
                          fields="section")

#Iterate through the rows in the cursor and print out the section value.
    for row in rows:
        print("section: {0}".format(
            row.getValue("B")))

我还将上述步骤添加到遵循的代码中:

# Local variables:
table1 = "C:\\Users\\myuser\\Documents\\mydatabase.gdb\\table1"
table2 = "C:\\Users\\myuser\\Documents\\mydatabase.gdb\\table2"
table3 = "C:\\Users\\myuser\\Documents\\mydatabase.gdb\\table3"
table1_a = table1
table1_b = table1_a
table1_c = table1_b
table1_d = table1_c
table1_e = table1_d
table3_a = table3
table1_end = table1_e

# Process: Add field in table1 for interim results
arcpy.AddField_management(talbe1, "costs_interim", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")

# Process: Join table1 and table2 via shared fields "code"
arcpy.JoinField_management(table_b, "code", table2, "code", "")

# Process: calculate field costs_interim
arcpy.CalculateField_management(table1_c, "costs_interim", "!area!* !a_value!", "")

#Summarize costs_interim according to their number

# Process: add field in table3
arcpy.AddField_management(table3, "costs_calc_interim", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")

# Process: join table1 and table3 via shared field "number"
arcpy.JoinField_management(table1_d, "number", table3_a, "number", "")

# Process: calculate endresult into field "cost_calc"
arcpy.CalculateField_management(table1_e, "costs_calc", "!costs_calc_interim! * !b_value! / 100", "")

这里是我生成新列(可以的),但是每次加入或计算一个新表都会生成新表。我希望临时生成表,因此最终结果不在新表中,而是在介绍中所述写入表3。

仍然缺少的是如何根据其在字段/列中的“ conse cost_interim”汇总“ cost_interim”。

I need to write a python script to automatically calculate costs into a given column by combining several tables (if possible using arcpy in ArcMap 10.7) but I’m struggling to do that since I’ve never actually done something like that.
Hence here I am, hoping that some kind soul in this community might be able to help me.
My tables have several columns, but I just listed the onces relevant for my calculations, for simplicity the tablenames will just be table1, table2, table3. Unfortunately, I don’t have any dummy data that I could post here…

My tables:

  • Table1, Columns: area(int), number(string), code(int), section(string)
  • Table2, Columns : code(int), a_value(double)
  • Table3, Columns : number(string), b _value(double),costs_calc(double)

Table1 and Table2 are connected via the ID in the respective column «code»
; Table1 and Table3 are connected via the number in the respective column «number»

Goal : script should automatically calculate costs in column «costs_calc» from values stored in 3 different tables…

Process I want to script (or how I figured the steps to get a result look like):

Step 1: Filter in Table1, from column « section » all rows with the
value «B» (only those rows with this value are needed for further
calculation, the other rows should not be included)

Step 2: Multiply Values in «a_value» (Table2) with all values from
«area» (Table1) (for all rows filtered in Step 1 – of course Step 1 and Step 2 can be swaped if it’s easier (not sure)) --Interim results could be written into a temporary table or into a new column in table1 – whatever is easier…

Step 3: Summarize the result calculated in Step 2 according to their number (Table1) (here I want all the calculated results combined/summarized according to their number -- after calculation there are for example 5 results for number 12345 (because their «code» is different) and these should be summarized into) interim results could be written into a temporary table or a new column in table3

Example for what I mean with "summarize calculated interim results (costs_interim) according to number", that's what should happen:
Table after calculation step 2
Table after summarizing step 3

Step 4: Results calculated in Step 3 (summarized values) should be multiplied with the values in column « b_value ». The results of this step will also be the final results and are thus written into the column «costs_calc» (Table3)

I know I can execute the first step by using the SearchCursor(arcpy)function but beyond that, I’m lost...
Hence I also have no code up to now except for import arcpy, math, etc. and setting the environment and a first try with the SearchCursor-function..

I’d be so very grateful for some hints, solutions or ideas!!

my first try:

fc="table1" fields = ['section','area'] delimfield = arcpy.AddFieldDelimiters(fc, fields[1]) cursor = arcpy.da.SearchCursor(fc, fields, delimfield +"= 'B'")

#Open a searchcursor
rows = arcpy.SearchCursor("c:/Users/myuser/mydatabase/table1",
                          fields="section")

#Iterate through the rows in the cursor and print out the section value.
    for row in rows:
        print("section: {0}".format(
            row.getValue("B")))

I've also added the mentioned steps as followed into the code:

# Local variables:
table1 = "C:\\Users\\myuser\\Documents\\mydatabase.gdb\\table1"
table2 = "C:\\Users\\myuser\\Documents\\mydatabase.gdb\\table2"
table3 = "C:\\Users\\myuser\\Documents\\mydatabase.gdb\\table3"
table1_a = table1
table1_b = table1_a
table1_c = table1_b
table1_d = table1_c
table1_e = table1_d
table3_a = table3
table1_end = table1_e

# Process: Add field in table1 for interim results
arcpy.AddField_management(talbe1, "costs_interim", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")

# Process: Join table1 and table2 via shared fields "code"
arcpy.JoinField_management(table_b, "code", table2, "code", "")

# Process: calculate field costs_interim
arcpy.CalculateField_management(table1_c, "costs_interim", "!area!* !a_value!", "")

#Summarize costs_interim according to their number

# Process: add field in table3
arcpy.AddField_management(table3, "costs_calc_interim", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")

# Process: join table1 and table3 via shared field "number"
arcpy.JoinField_management(table1_d, "number", table3_a, "number", "")

# Process: calculate endresult into field "cost_calc"
arcpy.CalculateField_management(table1_e, "costs_calc", "!costs_calc_interim! * !b_value! / 100", "")

The things here is that I generate new columns (which is ok) but with every join or calculation a new table gets generated. I'd prefer the tables to be generated temporarily, so that the final result is not in a new table but written into table3 as described in the intro.

What is still missing, is how to summarize the calculated field "costs__interim" according to their value in the field/column "number" before joining the tables in the step afterwards.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜尕妞 2025-02-14 09:11:20

对于第2步:
我建议您在“代码”列上加入OB表1和表2。这应该为您提供一张包含两个表的列的表。
接下来,在生成的加入表中创建一个新字段,该字段从列“ a_field”列乘以“列”区域“ a_field”的值,

这是指向加入和创建字段的文档的链接

创建字段: https://pro.arcgis.com/de/pro-app/2.8/tool-reference/data-management/add-field.htm

步骤3
这是一份文档,可以汇总字段

https ://pro.arcgis.com/de/pro-app/2.8/tool-reference/analisy/summary-statistics.htm

For step 2:
I propose that you Join ob Table 1 and Table 2 on the "Code" column. This should give you a Table containing the columns from both Tables.
Next, create a new field in the resulting join table that calculates the value from column "a_field" multiplied by value from column "area"

Here are links to documentations for join and creating fields

Join: https://pro.arcgis.com/de/pro-app/2.8/tool-reference/data-management/join-field.htm

Create field: https://pro.arcgis.com/de/pro-app/2.8/tool-reference/data-management/add-field.htm

For step 3
Here is a documentation to summarize fields

https://pro.arcgis.com/de/pro-app/2.8/tool-reference/analysis/summary-statistics.htm

贪恋 2025-02-14 09:11:20

更新:
我使用arcpy.tableselect而不是arcpy.da.da.searchcursor()
之后,如“添加”字段(Arcpy.addfield)和加入(Arcpy.Joinfield)的问题中已经提到的,以及摘要统计数据(最终似乎也有效)。
测试并确认它正在运行后,我将发布最终代码。

仍然对任何意见或想法开放

Update:
Instead of arcpy.da.SearchCursor() I used arcpy.TableSelect
afterwards as mentioned already in the questions just adding fields (arcpy.AddField) and joining (arcpy.JoinField), as well as the summary statistics (finally seems to work as well).
Once I test it and confirm it's running, I'll post the final code.

Still open for any inputs or ideas though

陌路终见情 2025-02-14 09:11:20

因此,最终且大部分清理的代码看起来像这样:

# Import system modules
import arcpy, arcgisscripting
from arcpy import env
from datetime import datetime
import os, os.path, sys, time, datetime, traceback, string, math, getpass
from re import sub
import pandas as pd
import numpy as np
import locale;
os.environ["PYTHONIOENCODING"] = "utf-8";
import re
reload(sys)
sys.setdefaultencoding('utf8')

arcpy.env.overwriteOutput = True

###############################################################################################################
# Variables
# Workspace - db
print "******************************************************************************************"
print "Workspace db"
print "******************************************************************************************"
workspace = "C:\datasources\MyProject\db" + '\\'
print 'Workspace:',                 workspace
db = workspace + "mydatabase.gdb"
backupdb = db.replace(".gdb", "_copy.gdb")
print 'db:       ',                 db
tempdb = db + '\\' + "tempDB.gdb"
tempgebuehren = workspace + "mydatabase_temp.gdb"
###############################################################################################################

# Create a copy of the db
arcpy.Copy_management(db, backupdb)

#User and timestamp
currentUser = getpass.getuser().upper()
arcpy.AddMessage("User: " + currentUser)
#currentTimestamp = str(datetime.datetime.now())
#arcpy.AddMessage("Timestamp: " + currentTimestamp)
expTimestamp = '''def add_date():
  import datetime
  return datetime.datetime.now()'''
# exp = '''def add_date():
#  import time
#  return time.strftime("%Y/%m/%d")'''

#set workspace environment
try:
   arcpy.env.workspace = db
   arcpy.AddMessage('Database read successfully ...')
except:
   arcpy.AddMessage('Database not found. Please try again')

#create temporary table for all calculations processes
try:
   arcpy.CreateFileGDB_management(workspace, "mydatabase_temp.gdb")
   arcpy.AddMessage('Database created successfully ...')
except:
   arcpy.AddMessage('Database could not be created. Please try again')

# set script parameter
TABLE1 = arcpy.GetParameterAsText(0)
if TABLE1 == '#' or not TABLE1:
    TABLE1 = db + '\\' + "TABLE1" # provide a default value if unspecified


table2 = arcpy.GetParameterAsText(1)
if table2 == '#' or not table2:
    table2 = db + '\\' + "AV" + '\\' + "table2" # provide a default value if unspecified


TABLE3 = arcpy.GetParameterAsText(2)
if TABLE3 == '#' or not TABLE3:
    TABLE3 = db + '\\' + "TABLE3" # provide a default value if unspecified


# Check if the Column u_value_type contains any NULL values and replace them with 0
with arcpy.da.UpdateCursor(table2, ["u_value_type"]) as cursor:
    for row in cursor:
        if row[0] == None:
            row[0] = 0
            cursor.updateRow(row)

arcpy.AddMessage('The column u_value_type contained NULL values and they were successfully replaced with 0')

del row

# Create a copy of the db
arcpy.Copy_management(db, backupdb)


# local variables (generated temporarily)
table2__2_ = table2

TABLE1_temp = workspace + '\\' + "mydatabase_temp.gdb" + '\\' + "TABLE1_temp"
TABLE1_temp__2_ = TABLE1_temp
TABLE1_temp__3_ = TABLE1_temp__2_
TABLE1_temp__4_ = TABLE1_temp__3_

table2__3_ = table2__2_
table2__4_ = table2__3_

TABLE3 = db + '\\' + "\\TABLE3"

TABLE1_SUM = workspace + '\\' + "mydatabase_temp.gdb" + '\\' + "TABLE1_SUM"


try:
# Calculation process
    arcpy.AddMessage('Starting calculation process ...')
# for column "sektion" select all rows with value "B" in table "TABLE1"
    arcpy.TableSelect_analysis(TABLE1, TABLE1_temp, "SEKTION = 'B'")
    arcpy.AddMessage('Filter table: ok')
# add a temporary field for later calculation results to table TABLE1
    arcpy.AddField_management(TABLE1_temp, "u_area_fees", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")
# join fields from table TABLE1 with table TABLE3 on art=code for later calculation over both tables
    arcpy.JoinField_management(TABLE1_temp__2_, "ART", TABLE3, "CODE", "CODE;u_cvalue")
    arcpy.AddMessage('join tables in temporary gdb: ok')
# calculate field from values of joined tables into newly added field
    arcpy.CalculateField_management(TABLE1_temp__3_, "u_area_fees", "!FLAECHE! * !u_cvalue!", "PYTHON", "")
    arcpy.AddMessage('temporary calculations: ok')
# summary statistics to merge all results according to their number
    arcpy.Statistics_analysis(TABLE1_temp__4_, TABLE1_SUM, "u_area_fees SUM", "NUMMER")
    arcpy.AddMessage('summarize fields: ok')
# join fields from tables fpr TABLE1 on table2 on number=number
    arcpy.JoinField_management(table2__2_, "NUMMER", TABLE1_SUM, "NUMMER", "NUMMER;SUM_u_area_fees")
    arcpy.AddMessage('join tables: ok')
# add field for results
    arcpy.AddField_management(table2__3_, "u_area_fees_noncalculated", "DOUBLE", "", "", "", "", "NULLABLE", "", "")
    arcpy.AddMessage('field added')
# calculate field
    arcpy.CalculateField_management(table2__3_, "u_area_fees_noncalculated", "(!u_value_type! / 100) * !SUM_u_area_fees!", "PYTHON", "")
    arcpy.AddMessage('interim results calculated')
# calculate endresult rounded
    arcpy.CalculateField_management(table2__4_, "u_area_fees_calculated", "math.ceil(!u_area_fees_noncalculated!)", "PYTHON", "")
    arcpy.AddMessage('...calculation process finished without errors')
except Exception,e:
    arcpy.AddMessage('Something went wrong. Please try again')
    arcpy.AddMessage("Fehler: " + str(e))


#delete temporary fields in table table2
try:
  arcpy.DeleteField_management(table2, ["NUMMER_1", "SUM_u_area_fees"])
  arcpy.AddMessage('Temporary fields successfully deleted...')
except:
   arcpy.AddMessage('Something went wrong, fields could not be deleted. Please try again')


#delete temporary FileGBD
try:
   arcpy.Delete_management(tempmydatabase)
   arcpy.AddMessage('Temporary database successfully deleted...')
except:
   arcpy.AddMessage('Ups, Something went wrong, could not delete Database. Please try again')

So the final and mostly cleaned up code looks like this:

# Import system modules
import arcpy, arcgisscripting
from arcpy import env
from datetime import datetime
import os, os.path, sys, time, datetime, traceback, string, math, getpass
from re import sub
import pandas as pd
import numpy as np
import locale;
os.environ["PYTHONIOENCODING"] = "utf-8";
import re
reload(sys)
sys.setdefaultencoding('utf8')

arcpy.env.overwriteOutput = True

###############################################################################################################
# Variables
# Workspace - db
print "******************************************************************************************"
print "Workspace db"
print "******************************************************************************************"
workspace = "C:\datasources\MyProject\db" + '\\'
print 'Workspace:',                 workspace
db = workspace + "mydatabase.gdb"
backupdb = db.replace(".gdb", "_copy.gdb")
print 'db:       ',                 db
tempdb = db + '\\' + "tempDB.gdb"
tempgebuehren = workspace + "mydatabase_temp.gdb"
###############################################################################################################

# Create a copy of the db
arcpy.Copy_management(db, backupdb)

#User and timestamp
currentUser = getpass.getuser().upper()
arcpy.AddMessage("User: " + currentUser)
#currentTimestamp = str(datetime.datetime.now())
#arcpy.AddMessage("Timestamp: " + currentTimestamp)
expTimestamp = '''def add_date():
  import datetime
  return datetime.datetime.now()'''
# exp = '''def add_date():
#  import time
#  return time.strftime("%Y/%m/%d")'''

#set workspace environment
try:
   arcpy.env.workspace = db
   arcpy.AddMessage('Database read successfully ...')
except:
   arcpy.AddMessage('Database not found. Please try again')

#create temporary table for all calculations processes
try:
   arcpy.CreateFileGDB_management(workspace, "mydatabase_temp.gdb")
   arcpy.AddMessage('Database created successfully ...')
except:
   arcpy.AddMessage('Database could not be created. Please try again')

# set script parameter
TABLE1 = arcpy.GetParameterAsText(0)
if TABLE1 == '#' or not TABLE1:
    TABLE1 = db + '\\' + "TABLE1" # provide a default value if unspecified


table2 = arcpy.GetParameterAsText(1)
if table2 == '#' or not table2:
    table2 = db + '\\' + "AV" + '\\' + "table2" # provide a default value if unspecified


TABLE3 = arcpy.GetParameterAsText(2)
if TABLE3 == '#' or not TABLE3:
    TABLE3 = db + '\\' + "TABLE3" # provide a default value if unspecified


# Check if the Column u_value_type contains any NULL values and replace them with 0
with arcpy.da.UpdateCursor(table2, ["u_value_type"]) as cursor:
    for row in cursor:
        if row[0] == None:
            row[0] = 0
            cursor.updateRow(row)

arcpy.AddMessage('The column u_value_type contained NULL values and they were successfully replaced with 0')

del row

# Create a copy of the db
arcpy.Copy_management(db, backupdb)


# local variables (generated temporarily)
table2__2_ = table2

TABLE1_temp = workspace + '\\' + "mydatabase_temp.gdb" + '\\' + "TABLE1_temp"
TABLE1_temp__2_ = TABLE1_temp
TABLE1_temp__3_ = TABLE1_temp__2_
TABLE1_temp__4_ = TABLE1_temp__3_

table2__3_ = table2__2_
table2__4_ = table2__3_

TABLE3 = db + '\\' + "\\TABLE3"

TABLE1_SUM = workspace + '\\' + "mydatabase_temp.gdb" + '\\' + "TABLE1_SUM"


try:
# Calculation process
    arcpy.AddMessage('Starting calculation process ...')
# for column "sektion" select all rows with value "B" in table "TABLE1"
    arcpy.TableSelect_analysis(TABLE1, TABLE1_temp, "SEKTION = 'B'")
    arcpy.AddMessage('Filter table: ok')
# add a temporary field for later calculation results to table TABLE1
    arcpy.AddField_management(TABLE1_temp, "u_area_fees", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")
# join fields from table TABLE1 with table TABLE3 on art=code for later calculation over both tables
    arcpy.JoinField_management(TABLE1_temp__2_, "ART", TABLE3, "CODE", "CODE;u_cvalue")
    arcpy.AddMessage('join tables in temporary gdb: ok')
# calculate field from values of joined tables into newly added field
    arcpy.CalculateField_management(TABLE1_temp__3_, "u_area_fees", "!FLAECHE! * !u_cvalue!", "PYTHON", "")
    arcpy.AddMessage('temporary calculations: ok')
# summary statistics to merge all results according to their number
    arcpy.Statistics_analysis(TABLE1_temp__4_, TABLE1_SUM, "u_area_fees SUM", "NUMMER")
    arcpy.AddMessage('summarize fields: ok')
# join fields from tables fpr TABLE1 on table2 on number=number
    arcpy.JoinField_management(table2__2_, "NUMMER", TABLE1_SUM, "NUMMER", "NUMMER;SUM_u_area_fees")
    arcpy.AddMessage('join tables: ok')
# add field for results
    arcpy.AddField_management(table2__3_, "u_area_fees_noncalculated", "DOUBLE", "", "", "", "", "NULLABLE", "", "")
    arcpy.AddMessage('field added')
# calculate field
    arcpy.CalculateField_management(table2__3_, "u_area_fees_noncalculated", "(!u_value_type! / 100) * !SUM_u_area_fees!", "PYTHON", "")
    arcpy.AddMessage('interim results calculated')
# calculate endresult rounded
    arcpy.CalculateField_management(table2__4_, "u_area_fees_calculated", "math.ceil(!u_area_fees_noncalculated!)", "PYTHON", "")
    arcpy.AddMessage('...calculation process finished without errors')
except Exception,e:
    arcpy.AddMessage('Something went wrong. Please try again')
    arcpy.AddMessage("Fehler: " + str(e))


#delete temporary fields in table table2
try:
  arcpy.DeleteField_management(table2, ["NUMMER_1", "SUM_u_area_fees"])
  arcpy.AddMessage('Temporary fields successfully deleted...')
except:
   arcpy.AddMessage('Something went wrong, fields could not be deleted. Please try again')


#delete temporary FileGBD
try:
   arcpy.Delete_management(tempmydatabase)
   arcpy.AddMessage('Temporary database successfully deleted...')
except:
   arcpy.AddMessage('Ups, Something went wrong, could not delete Database. Please try again')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文