5 votos

Tabla de resumen con un campo que muestra los componentes de cada registro resumido

Tengo una tabla con 2 campos el primero es para la comunidad y el segundo para la principal comunidad que pertenece, como en la imagenTable 1

Quiero resumir el segundo campo (Belongs_to) pero con un campo adicional (campo de valor múltiples) muestra los componentes de cada comunidad principal, como en la imagenenter image description here

¿Podría alguien ayudarme por favor?

27voto

Geog Puntos 1604

Utilice la herramienta de Tabla dinámica para transformar la tabla de salida en una tabla que contiene un registro para cada "zona" con atributos de la clase como atributo independiente. Esto crea una tabla de la mesa de entrada reducir redundancia en registros y aplastando las relaciones uno a muchos.

6voto

Aaron Puntos 25882

Hay una secuencia de comandos de la herramienta llamada "Concatenar los Valores de Fila" que hace exactamente lo que usted desea. Está disponible para su descarga aquí. También hay una entrada de blog acerca de esta herramienta de secuencia de comandos. Todo lo que tienes que hacer es agregar un campo a su FeatureClass donde los valores concatenados será escrito y resumir.

enter image description here

enter image description here

Para aquellos interesados en ver la secuencia de comandos:

# Import system modules
import sys, traceback, arcpy


#Define AddPrintMessage
def AddPrintMessage(msg, severity):
    print msg
    if severity == 0: arcpy.AddMessage(msg)
    elif severity == 1: arcpy.AddWarning(msg)
    elif severity == 2: arcpy.AddError(msg)


try:

    # Set the parameters
    InputTable = arcpy.GetParameterAsText(0)  
    if (InputTable == ''):
       arcpy.AddError("No input provided")


    CaseField = arcpy.GetParameterAsText(1)   
    if (CaseField == ''):
        arcpy.AddError("No iterate field provided. The iteration will be based on unique values")


    ReadFromField = arcpy.GetParameterAsText(2)   
    if (ReadFromField == ''):
        arcpy.AddError("No field provided to read the values from")


    CopyToField = arcpy.GetParameterAsText(3)  
    if (CopyToField == ''):
        arcpy.AddError("No field provided to copy the values to")


    Delimiter = arcpy.GetParameterAsText(4) 


    # Validate the inputs that are provided for field type.
    # A text field value can only be copied to a text type field, and
    # The numric field values with a delimiter can only be copied to a text type field.
    # Short Integer can be copied to field of type text, short integer, long integer, single or double without a delimiter.


    if arcpy.ListFields(InputTable, ReadFromField)[0].type == "String":
        if arcpy.ListFields(InputTable, CopyToField)[0].type == "String":
            ""
        else:
            arcpy.AddError("Copy To Field must be of type text when Read From Field is of type text.")            

    else:
        if arcpy.ListFields(InputTable, CopyToField)[0].type == "String":
            ""
        else:
            if Delimiter != "":
                arcpy.AddError("Copy To Field must be of type text when Read From Field is of type numeric or date and you are using a delimiter.")

            if Delimiter == "":
                if arcpy.ListFields(InputTable, ReadFromField)[0].type == "SmallInteger":
                    if arcpy.ListFields(InputTable, CopyToField)[0].type in ["Integer",  "SmallInteger", "Single", "Double"]:
                        ""                      
                    else:
                        if arcpy.ListFields(InputTable, CopyToField)[0].type == "Date":
                            arcpy.AddError("Copy To Field must be of type text.")

                if arcpy.ListFields(InputTable, ReadFromField)[0].type == "Integer":
                    if arcpy.ListFields(InputTable, CopyToField)[0].type in ["SmallInteger", "Integer", "Single", "Double", "Date"]:
                        arcpy.AddError("Copy To Field must be of type text.")

                else:
                    if arcpy.ListFields(InputTable, ReadFromField)[0].type in ["Single", "Double" , "Date"]:
                        if arcpy.ListFields(InputTable, CopyToField)[0].type in ["Integer", "SmallInteger", "Single", "Double" , "Date"]:
                            arcpy.AddError("Copy To Field must be of type text.")

    # Create an empty dictionary.
    dictionary = {}

    # Create a variable and set its value to the last row value. The first one is -1 which means no row before the first.
    lastid = -1


    # Create an empty variable which will store the value of the last row in the code below.
    lastvalue = ""


    # Insert Search cursor on a feature class or table to iterate through row objects and extract field values.
    # Sort values of a Search Cursor based on the CaseField and ReadFromField in ascending order.
    # Define what will happen once the curser moves through each row.
    # While it is in each row it will get the value of CaseField field that you are using as id to iterate.
    # While it is in row it will also get the value of the ReadFromField field that you want to concatenate.
    # Set the value of the dictionary to the values read by the cursor from the ReadFromField.
    # Set an if condition for what should the cursor do when it reads through fields with same ID or the CaseField value.
    # In if condition set the new value to last value of the ReadFromField + the defined delimiter + the new value that is read.
    # Again set the dictionary value to this new value.
    # Set the loop to have the lastid to the id that you got from getValue before it goes through the seconnd loop and so on...
    # Set the loops last value variable to the last value that was read such that it starts with that last value for the second loop and so on...


    cur1 = arcpy.SearchCursor(InputTable, "", "", "", CaseField +" A;" + ReadFromField +" A")

    for row in cur1:
        id = row.getValue(CaseField)
        value = row.getValue(ReadFromField)
        dictionary[id] = value        
        if id == lastid:
            value = str(lastvalue) + Delimiter + str(value)
            dictionary[id] = value
        lastid = id
        lastvalue = value


    # Delete cursor and row objects to remove the lock on the data that will remain until either the
    # script completes or the cursor object is deleted. 
    del cur1, row



    # Insert Update cursor to update or delete rows on the specified feature class, shapefile, or table. 
    # Define what will happen once the curser moves through each row.
    # While you are in each row set the cursor to get the value of the CaseField that is used as Id to iterate.
    # Set the value of the field that the concatenated values should be written to with the dictionary values that you concatenated in the code above.
    # Set the cursor to update the row values with the dictionary values.

    cur2 = arcpy.UpdateCursor(InputTable) 
    for row in cur2:
        id = row.getValue(CaseField)
        row.setValue(CopyToField, dictionary[id])
        cur2.updateRow(row)


    # Delete cursor and row objects to remove the lock on the data that will remain until either the
    # script completes or the cursor object is deleted. 
    del cur2, row


    # If you are using the tool in ModelBuilder, set the derived output parameter to the value
    # of input table so that it is not empty and can be used with other tools.
    arcpy.SetParameterAsText(5, str(InputTable))


except:
    tb = sys.exc_info()[2]
    tbinfo = traceback.format_tb(tb)[0]
    pymsg = "PYTHON ERRORS:\nTraceback Info:\n" + tbinfo + "\nError Info:\n    " + \
            str(sys.exc_type)+ ": " + str(sys.exc_value) + "\n"
    AddPrintMessage(pymsg, 2)
    msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"
    AddPrintMessage(msgs, 2)   

0voto

Harbhag Puntos 202

Pruebe esta solución en Excel. Es torpe pero funcionó para mí.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X