comparing two arrays

Discussion in 'Python' started by Sheldon, Jun 19, 2006.

  1. Sheldon

    Sheldon Guest

    Hi,

    I have two arrays that are identical and contain 1s and zeros. Only the
    ones are valid and I need to know where both arrays have ones in the
    same position. I thought logical_and would work but this example proves
    otherwise:
    0

    The where() statement is also worhtless here. Does anyone have any
    suggestion on how to do this?

    Thanks in advance,
    Sheldon
     
    Sheldon, Jun 19, 2006
    #1
    1. Advertisements

  2. Obviously they aren't identical. They may be of same size.

    print [i for i, _ in enumerate((None for v in zip(a, b) where v == (1,1)))]

    should give you the list of indices.

    Diez
     
    Diez B. Roggisch, Jun 19, 2006
    #2
    1. Advertisements

  3. Sheldon

    Bas Guest

    You are comparing a normal python list to a constant, which are
    obviously unequal. Try converting your lists to arrays first
    (untested):

    import numeric/numpy as N
    a =N.array([0,1,2,5,6,6])
    b = N.array([5,4,1,6,4,6])
    print a==6 and b==6
    print N.where(a==6 and b==6)

    hth,
    Bas


     
    Bas, Jun 19, 2006
    #3
  4. I musunderstood your question. Use


    print [i for i, _ in enumerate((None for x, y in zip(a, b) where x == y))]

    instead.

    Diez
     
    Diez B. Roggisch, Jun 19, 2006
    #4
  5. Sheldon

    Robert Kern Guest

    Careful there. The "and" keyword cannot be overloaded and so neither Numeric nor
    numpy does. Either N.logical_and() should be used or (since the results of a==6
    and b==6 are known to be boolean arrays) the & operator works fine as well.


    In [9]: import numpy as np

    In [10]: a = np.array([0,1,2,5,6,6])

    In [11]: b = np.array([5,4,1,6,4,6])

    In [12]: (a==6) & (b==6)
    Out[12]: array([False, False, False, False, False, True], dtype=bool)

    In [13]: np.where((a==6) & (b==6))
    Out[13]: (array([5]),)


    The OP may also find that numpy questions are best handled on numpy-discussion
    rather than comp.lang.python .

    https://lists.sourceforge.net/lists/listinfo/numpy-discussion

    --
    Robert Kern

    "I have come to believe that the whole world is an enigma, a harmless enigma
    that is made terrible by our own mad attempt to interpret it as though it had
    an underlying truth."
    -- Umberto Eco
     
    Robert Kern, Jun 19, 2006
    #5
  6. Sheldon

    Sheldon Guest

    Diez B. Roggisch skrev:
    Hi Diez,

    I wish I say that I understood what you wrote here but I can't.
    Do you mind explaining a little more?

    /sheldon
     
    Sheldon, Jun 20, 2006
    #6
  7. print [i for i, _ in enumerate((None for x, y in zip(a, b) where x ==
    I actually made a typo, instead of "where" in the above use "if". and the
    whole thing won't compute what you are after. This will:

    [i for i, equals in enumerate((x == y for x, y in zip(a, b))) if equals]

    Sorry for that.

    Its a nested list-comprehension. Actually, the outer thingy is a
    list-comprehension while the inner is a generator expression. There is of
    course a difference, but for now this doesn't matter too much.

    a list comprehension of form

    [<expression> for <variable> in <iterable> if <condition>]

    is a more compact form for

    result = []
    for <variable> in <iterable>:
    if <condition>:
    result.append(<expression>)


    A generator expression works the same with () instead of [].

    Now let's decompose the above statment:

    (x == y for x, y in zip(a, b) ))

    <variable> = x, y
    <iterable> = zip(a, b)
    <expression> = x == y

    So: the iterable is returned by the function zip. That is a built-in which
    will take 2 or more lists and return a list of tuples, where the first
    element is from the first list, then the second and so on. So your example
    lists become:

    a = [0,1,2,5,6,6]
    b = [5,4,1,6,4,6]
    zip(a, b) = [(0,5), (1,4), (2,1), (5,6), (6,4), (6,6)]

    So iterating over this yields the pairs of (0,5) and so forth.

    Next thing is that with

    x, y = p

    python unpacks a tuple and refers to its contents by name x for the first
    one and y for the second. So overall, we loop in sync over both lists, and
    getting x and y to point to the corresponding elements.

    Now the expression x == y will result True if x == y - False otherwise.

    So the result of the inner listcomp/genexp looks like this:

    res = [False, False, False, False, False, True]

    As you can see: for each pair x,y in the original lists we come up with the
    result of comparing them.

    Now the outer listcomp using "res" instead of the genexps for clarity reads
    like this:



    [i for i, equals in enumerate(res) if equals]

    <variable> = i, equals
    <iterable> = enumerate(res)
    <expression> = i
    <condition> = equals

    enumerate is another built-in that takes an iterable and returns a tuple of

    (pos, element)

    for each element in the iterable.

    So for our list, it will return:

    [(0, False), (1, False), (2, False), (3, False), (4, False), (5, True)]

    These tupkes values are assigened to i and equals for each element of the
    above list. The condtion

    equals

    will then guarantee that only those expressions are evaluated where equals
    is True - the last pair, so to speak. The expression then only stores the
    index i. Which will give us the desired result.

    Diez
     
    Diez B. Roggisch, Jun 20, 2006
    #7
  8. Le Mardi 20 Juin 2006 12:09, Diez B. Roggisch a écrit :
    No needs to nest comprehensions, should be :

    [ i for i, v in enumerate(zip(a, b)) if v[0] == v[1] ]


    --
    _____________

    Maric Michaud
    _____________

    Aristote - www.aristote.info
    3 place des tapis
    69004 Lyon
    Tel: +33 426 880 097
     
    Maric Michaud, Jun 20, 2006
    #8
  9. You're right, that design stemmed from my first broken version.

    Diez
     
    Diez B. Roggisch, Jun 20, 2006
    #9
  10. Or even deconstruct to avoid the (very mildly confusing) v[0], v[1]:

    [i for i, (left, right) in enumerate(zip(a, b)) if left == right]
     
    Scott David Daniels, Jun 20, 2006
    #10
  11. Sheldon

    Sheldon Guest

    Thanks Diez,

    It will take a little while for this one to sink in but it gets the job
    done now and will for future cases.

    /Sheldon

    Diez B. Roggisch skrev:
     
    Sheldon, Jun 22, 2006
    #11
  12. Sheldon

    Sheldon Guest

    Thanks Diez,

    It will take a little while for this one to sink in but it gets the job
    done now and will for future cases.

    /Sheldon

    Diez B. Roggisch skrev:
     
    Sheldon, Jun 22, 2006
    #12
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.