简体   繁体   中英

Python: Updating a list or array within a while loop

I have a numpy array of numpy arrays (would be happy to work with a list of numpy arrays), and I want to edit the overall array. More specifically, I check if arrays (within the larger array) share values, and if they do, I remove the shared values from the smaller array.

The issue I'm having is that when I try to reinsert the modified arrays into the all encompassing array, the final output when the while loop is finished does not remember the updated modules.

I believe this is something to do with pythons nuances of copy/view items, and that when I access element i or j of the overall array, I'm making a new object within the while loop rather than editing the element within the larger array. However, I'm happy to admit I don't fully understand this and definitively can't think of an alternative despite hours of trying.

#Feature_Modules is an array (or list) of number arrays, each containing a set of integers
i = 0
j = 0
while i < Feature_Modules.shape[0]: # Check element i against every other element j
    if i != j:
        Ref_Module = Feature_Modules[i]
        while j < Feature_Modules.shape[0]:
            if i != j:
                Query_Module = Feature_Modules[j]
                if np.array_equal(np.sort(Ref_Module),np.sort(Query_Module)) == 1: # If modules contain exactly the same integers, delete one of this. This bit actually works and is outputted at the end.
                    Feature_Modules = np.delete(Feature_Modules,j)
                Shared_Features = np.intersect1d(Ref_Module, Query_Module)
                if Shared_Features.shape[0] > 0 and np.array_equal(np.sort(Ref_Module),np.sort(Query_Module)) == 0: # If the modules share elements, remove the shared elements from the smaller module. This is the bit that isn't outputted in the final Feature_Modules object.
                    Module_Cardinalities = np.array([Ref_Module.shape[0],Query_Module.shape[0]])
                    Smaller_Group = np.where(Module_Cardinalities == np.min(Module_Cardinalities))[0][0]
                    New_Groups = np.array([Ref_Module,Query_Module])
                    New_Groups[Smaller_Group] = np.delete(New_Groups[Smaller_Group],np.where(np.isin(New_Groups[Smaller_Group],Shared_Features) == 1))
                    Feature_Modules = Feature_Modules.copy()
                    Feature_Modules[i] = New_Groups[0] # Replace the current module of Feature_Modules with the new module (Isn't outputted at end of while loops)
                    Feature_Modules[j] = New_Groups[1] # Replace the current module of Feature_Modules with the new module (Isn't outputted at end of while loops)
                else:
                    j = j + 1
            else:
                j = j + 1
    else:
        i = i + 1
    i = i + 1

So if we use this small data set as an example,

Feature_Modules = np.array([np.array([1,2,3,4,5,6,7,8]),np.array([9,10,1,2,3,4]), np.array([20,21,22,23])])

The new Feature_Modules should be;

Feature_Modules = np.array([np.array([1,2,3,4,5,6,7,8]), np.array([9,10]), np.array([20,21,22,23])])

since the shared values in array's [0] and [1], were removed from the [1] as it was the smaller array.

I would suggest taking a more python X numpy approach to the code:

import numpy as np

Feature_Modules = np.array([np.array([1,2,3,4,5,6,7,8]), np.array([9,10,1,2,3,4]), np.array([20,21,22,23])])

for n1,arr1 in enumerate(Feature_Modules[:-1]):
    l1 = len(arr1)
    for n2,arr2 in enumerate(Feature_Modules[n1+1:]):
        l2 = len(arr2)
        intersect, ind1, ind2 = np.intersect1d(arr1, arr2, return_indices=True)
        if len(intersect) == 0:
            continue
        if l1 > l2:
            Feature_Modules[n2+n1+1] = np.delete(arr2, ind2)
        else:
            Feature_Modules[n1] = np.delete(arr1, ind1)

# [array([1, 2, 3, 4, 5, 6, 7, 8]) array([ 9, 10]) array([20, 21, 22, 23])]

EDIT:

This code will edit the original array in order to keep track of the list that already had element removed. If you want to leave the original array untached, just make a copy of it:

copy = np.array(original)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM