Объединяйте элементы, просматривая данные - PullRequest
0 голосов
/ 11 марта 2020

У меня есть некоторые данные в форме:

ID A B VALUE         EXPECTED RESULT
1  1 2 5               GROUP1
2  2 3 5               GROUP1
3  3 4 6               GROUP2
4  3 5 5               GROUP1
5  6 4 5               GROUP3

Что я хочу сделать, это перебрать данные (тысячи строк) и создать общее поле, чтобы я мог легко объединить данные (* A-> start Node, B-> End Node Value-> Order ... данные образуют нечто вроде цепочки, в которой только соседи имеют общие A или B)

Правила присоединения:

  1. равное значение для всех элементов группы

  2. A элемента один, равный B элемента два (или противоположное, но НЕ A = A 'или B = B ')

  3. Самый сложный: назначить одной и той же группе все последовательные данные, которые образуют серию пересекающихся узлов.

То есть первый элемент [1 1 2 5] должен быть соединен с [2 2 3 5], а затем с [4 3 5 5]

Любой Идея, как сделать это sh надежно при переборе большого количества данных? У меня проблема с правилом № 3, остальные легко применяются. Для ограниченных данных у меня есть некоторый успех, но это зависит от порядка, в котором я начинаю проверять данные. И это не работает для большого набора данных. Я могу использовать arcpy (предпочтительно) или даже Python или R или Matlab, чтобы решить эту проблему. Попробовал arcpy безуспешно, поэтому я проверяю альтернативы.

В ArcPy этот код работает нормально, но с ограниченным расширением (т. Е. В больших объектах со многими сегментами вместо этого я получаю 3-4 группы) из 1):

TheShapefile="c:/Temp/temp.shp"
desc = arcpy.Describe(TheShapefile)
flds = desc.fields
fldin = 'no'
for fld in flds:        #Check if new field exists
    if fld.name == 'new':
        fldin = 'yes'
if fldin!='yes':                    #If not create
    arcpy.AddField_management(TheShapefile, "new", "SHORT")
arcpy.CalculateField_management(TheShapefile,"new",'!FID!', "PYTHON_9.3")  # Copy FID to new
with arcpy.da.SearchCursor(TheShapefile, ["FID","NODE_A","NODE_B","ORDER_","new"]) as TheSearch:
    for SearchRow in TheSearch:
        if SearchRow[1]==SearchRow[4]:
            Outer_FID=SearchRow[0]
        else:
            Outer_FID=SearchRow[4]
        Outer_NODEA=SearchRow[1]
        Outer_NODEB=SearchRow[2]
        Outer_ORDER=SearchRow[3]
        Outer_NEW=SearchRow[4]
        with arcpy.da.UpdateCursor(TheShapefile, ["FID","NODE_A","NODE_B","ORDER_","new"]) as TheUpdate:
                    for UpdateRow in TheUpdate:
                        Inner_FID=UpdateRow[0]
                        Inner_NODEA=UpdateRow[1]
                        Inner_NODEB=UpdateRow[2]
                        Inner_ORDER=UpdateRow[3]
                        if Inner_ORDER==Outer_ORDER and (Inner_NODEA==Outer_NODEB or Inner_NODEB==Outer_NODEA):
                            UpdateRow[4]=Outer_FID
                            TheUpdate.updateRow(UpdateRow)

И некоторые данные в форме шейп-файла и в формате DBF

1 Ответ

2 голосов
/ 11 марта 2020

Использование matlab:

A = [1 1 2 5               
     2 2 3 5               
     3 3 4 6               
     4 3 5 5
     5 6 4 5]               

%% Initialization
% index of matrix line sharing the same group     
ind = 1 
% length of the index
len = length(ind)
% the group array
g   = []
% group counter
c   = 1

% Start the small algorithm
while 1
    % Check if another line with the same "Value" share some common node
    ind = find(any(ismember(A(:,2:3),A(ind,2:3)) & A(:,4) == A(ind(end),4),2));

    % If there is no new line, we create a group with the discovered line
    if length(ind) == len
        %group assignment
        g(A(ind,1)) = c
        c = c+1
        % delete the already discovered line (or node...)
        A(ind,:) = []
        % break if no more node
        if isempty(A)
            break
        end
        % reset the index for the next group
        ind = 1;
    end
    len = length(ind);
end

А вот вывод:

g =

   1   1   2   1   3

Как и ожидалось

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