Рассчитать процентные ранги по группам, используя Numpy - PullRequest
0 голосов
/ 01 октября 2018

Я очень плохо знаком с Python и хочу рассчитать процентильные ранги по группам.Моя группа - единица управления дикой природой (WMU - строка), а ранги основаны на значении прогнозируемой плотности лося (PMDEN3 - FLOAT).Значение ранга переходит в поле RankMD.

Мой подход состоял в том, чтобы использовать цикл for для вычисления 3 рангов в каждом WMU, но в результате было создано 3 ранга для всего файла dbf (около 23 000 записей), без учета WMU.Любая помощь очень ценится.

import arcpy
import numpy as np

input = r'K:\Moose\KrigStratPython\TestRank3.dbf' 
arr = arcpy.da.TableToNumPyArray(input, ('PMDEN3', 'Wmu'))
c_arr = [float(x[0]) for x in np.ndarray.flatten(arr)]

for Wmu in arr:
##to create 3 rank for example
    p1 = np.percentile(c_arr, 33)  # rank = 0
    p2 = np.percentile(c_arr, 67)  # rank = 1
    p3 = np.percentile(c_arr, 100)  # rank = 2

#use cursor to update the new rank field
    with arcpy.da.UpdateCursor(input , ['PMDEN3','RankMD']) as cursor:
        for row in cursor:
            if row[0] < p1:
                row[1] = 0  #rank 0
            elif p1 <= row[0] and row[0] < p2:
                 row[1] = 1
            else:
                 row[1] = 2

            cursor.updateRow(row)

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

По предложению BigGerman я пересмотрел свой код, и теперь он работает.Скрипт просматривает каждое значение WMU и вычисляет процентиль ранга в каждой группе на основе PMDEN.Чтобы улучшить скрипт, я должен создать массив значений WMU из моего входного файла, а не создавать массив вручную.

import arcpy
import numpy as np

#fields to be calculated
fldPMDEN = "PMDEN"
fldRankWMU = "RankWMU"

input = r'K:\Moose\KrigStratPython\TestRank3.dbf' 
arcpy.MakeFeatureLayer_management(input, "stratLayerShpNoNullsLyr")
WMUs = ["10", "11A", "11B", "11Q", "12A"]
for current_wmu in WMUs:
    ##to create 3 rank for example
        where_clause = "Wmu = '{}'".format(current_wmu)  # format the above variable into a query
        with arcpy.da.UpdateCursor("stratLayerShpNoNullsLyr", [fldPMDEN,fldRankWMU], where_clause) as cursor:
            arr1 = arcpy.da.TableToNumPyArray("stratLayerShpNoNullsLyr", [fldPMDEN,fldRankWMU], where_clause)
            c_arrS = [float(x[0]) for x in np.ndarray.flatten(arr1)]
            p1 = np.percentile(c_arrS, 33)  # rank = 3
            p2 = np.percentile(c_arrS, 67)  # rank = 2
            p3 = np.percentile(c_arrS, 100)  # rank = 1 (highest density)
            for row in cursor:
                if row[0] < p1:
                    row[1] = 3  #rank 0
                elif p1 <= row[0] and row[0] < p2:
                     row[1] = 2
                else:
                     row[1] = 1
                cursor.updateRow(row)
0 голосов
/ 02 октября 2018

Ваш цикл for правильный, однако ваш UpdateCursor выполняет итерацию по всем строкам таблицы.Чтобы получить желаемый результат, вам нужно выбрать подмножество таблицы, а затем использовать курсор обновления на нем.Это можно сделать, передав запрос параметру where_clause функции UpdateCursor .

Таким образом, у вас будет такой запрос:

current_wmu = WMU['wmu']  # This should be the value of the wmu that the for loop is currently on I think it would be WMU['wmu'] but i'm not positive
where_clause = "WMU = '{}'".format(current_wmu)  # format the above variable into a query string

, и тогда ваш UpdateCursor теперь будет:

with arcpy.da.UpdateCursor(input , ['PMDEN3','RankMD'], where_clause) as cursor:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...