12 votos

¿Cómo calcular un nuevo atributo basado en cambios en otro atributo?

Estoy tratando de clasificar un conjunto de gps vez codificados los datos del punto en comportamientos basados en atributos diferentes. He creado un atributo que es 0 para el hogar y 1 para la distancia basados en la ubicación, y ahora quiere que el número de viajes lejos de casa (un conjunto de puntos 01111111111110 sería un viaje, ya que comenzó y terminó en la casa). He añadido el campo de atributo que tendrán los números de viaje, pero no sé cómo calcular el campo por lo que se basa en la casa/fuera de campo.

Aquí es un ejemplo de los datos del GPS (el uso de "*" para indicar la información irrelevante y simplemente indexación veces como 1, 2, etc.), la "Casa/Fuera" indicador descrito anteriormente, y el indicador de disparo, "Viaje", que necesito para calcular:

Time Lat Lon Home/Away Trip
   1   *   *         0    0
   2   *   *         1    1
   3   *   *         1    1
....
  12   *   *         1    1
  13   *   *         0    0
  14   *   *         0    0
  15   *   *         1    2
  16   *   *         1    2
.... 
  34   *   *         1    2
  35   *   *         0    0
  36   *   *         0    0
  37   *   *         1    3
....

Mi conjunto de datos es demasiado grande para pasar manualmente a través de y el número de cada viaje en la tabla de atributos, así que es allí cualquier manera de calcular el campo que se basa en cómo la casa/fuera atributo es ordenado y cada "grupo" de distancia de los puntos es designado como un viaje?

ACTUALIZACIÓN: estos son los desnudos huesos de lo que el código de Python que podría parecer (no tengo experiencia con el código).

Expresión:

trip = Reclass(!home!)

Codeblock:

def Reclass(home):  
  if (home = 0):  
    return 0   
  elif (home = 1 and lastValue = 0):  
    return _(incremental numbering?)_  
  elif (home = 1 and lastValue = 1):  
    return lastValue  

ACTUALIZACIÓN:
Después de usar matt wilkie recomienda script que he hecho algunos cambios para que mi primer viaje es el número 1, mi segunda el 2, etc etc. Aquí está el código modificado de matt:

import arcpy
rows = arcpy.UpdateCursor("test2")

trip = 0
for row in rows:
    if row.home == 0:
        prev = row.home
        row.TRIP = trip
        rows.updateRow(row)

    elif row.home == 1 and prev == 0:
        trip += 1
        prev = row.home
        row.TRIP = trip
        rows.updateRow(row)
        rows.next()

    elif row.home == 1 and prev == 1:
        prev = row.home
        row.TRIP = trip
        rows.updateRow(row)
        rows.next()

    row.TRIP = trip
    rows.updateRow(row)


del row, rows

A continuación, sólo tienes que seleccionar para el hogar = 0 y calcular mi viaje de campo a 0. Ordenado viajes. Un millón de gracias a todos!

12voto

Greg Puntos 1756

Para ello se puede utilizar UpdateCursor, que se abre a la clase de entidad o tabla y los pasos a través de cada registro (fila) de forma incremental.

El siguiente script funciona en estos datos de prueba

+-----------------------+
| Time| Home_Away|Trip  |
+-----|----------|------+
|  1  |  0       | <nul>|
|  2  |  1       | <nul>|
|  4  |  1       | <nul>|
|  5  |  0       | <nul>|
|  6  |  0       | <nul>|
|  7  |  1       | <nul>|
|  9  |  1       | <nul>|
| 12  |  1       | <nul>|
| 13  |  0       | <nul>|
+-----------------------+

.

import arcpy
fc = r'D:\s\py\pyscratch.gdb\gps_points'

# open the feature class and create the cursor
rows = arcpy.UpdateCursor(fc)

trip = 0
for row in rows:
    if row.HOME_AWAY == 0:
        trip += 1           # start of new trip, increment counter
        row.TRIP = trip     # calc the TRIP field to be current trip#
        rows.updateRow(row) # save
        print "Trip %s started at %s" % (trip, row.TIME)

    # keep cycling through records until HOME_AWAY is not 1
    while row.HOME_AWAY == 1:
        row.TRIP = trip
        rows.updateRow(row)
        rows.next() # move to next record

    # this is for the trailing end of a trip, the second 0
    # print "     %s ended at %s" % (trip, row.TIME)
    row.TRIP = trip
    rows.updateRow(row)

# remove programming objects and data locks
# the data itself is left alone
del row, rows

El extremo final de viaje bloque que se ejecuta para el comienzo de un viaje también, pero ya que el viaje contador es correcta la doble calc en el comienzo de un viaje-fila no importa . Quite el comentario de la instrucción print en ese bloque para ver a qué me refiero.

Python agrega automáticamente un implícito rows.next() al final de la for row in rows bloque.

Esto supone la integridad de los datos. Se hace un lío si cada vez hay un número impar de cero en Casa/Fuera registros en una fila (000 o 00000). Un viaje que sólo se compone de inicio y de parada debe estar bien, por ejemplo, un viaje de 3 secuencia de 01..10 00 01..10 , donde los espacios denotar las brechas entre los viajes. En otras palabras, validar los resultados!

5voto

cjstehno Puntos 131

El ArcGIS 10 en "calcular el campo" ejemplos se muestra cómo Calcular el acumulado de valor de un campo numérico." Esto va a hacer el truco, siempre y cuando los datos están físicamente en el orden temporal.

Para aplicar directamente, invertir su [Home/Away] indicador (restar de 1), de modo que el "0" significa "lejos" y "1" significa "casa". Yo llamo a esto [/Inicio] en el ejemplo de abajo.

Calcular el valor acumulado--[Acumulativa] en el ejemplo.

Agregar uno y dividir por dos--[Viaje] en el ejemplo de (casi).

Por último, establezca [Viaje] a cero para todos los de la "casa" de los registros. Ahora los resultados están de acuerdo con el ejemplo:

Time Lat Lon Home/Away Trip Away/Home Cumulative 
   1   *   *         0    0         1          1
   2   *   *         1    1         0          1
   3   *   *         1    1         0          1
.... 
  12   *   *         1    1         0          1
  13   *   *         0    0         1          2
  14   *   *         0    0         1          3
  15   *   *         1    2         0          3
  16   *   *         1    2         0          3
.... 
  34   *   *         1    2         0          3
  35   *   *         0    0         1          4
  36   *   *         0    0         1          5
  37   *   *         1    3         0          5
....

Para el registro, aquí está el código tomado de la ayuda de ArcGIS 10. He modificado un poco para hacer cada paso a la vez: ahora solo necesitas ejecutarlo. Se debe tener claro donde [Home/Away] se invierte y donde el "add 1, dividir por 2" paso se produce.

Expresión:

acc(!Home/Away!)

Tipo De La Expresión:

PYTHON_9.3

Bloque De Código:

t=0
def acc(i):
  global t
  if t:
    t += (1-i)
  else:
    t = 1
  if i:
    return (t+1)/2
  else:
    return 0

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