3

If I have an array with 4 int

[a,b,c,d]

and I want a difference between each element to another element, which the result looks like:

[a-b, a-c, a-d,b-c,b-d,c-d]

The sign does matter, I try shift the array, but there should be a better way to do this, Cause this seems like some math problem that I forgot.

import numpy as np

array_1 = np.array([1,2,3,4])

array_2 = np.copy(array_1)
array_2 = np.roll(array_2,-1)
array_2[-1] = 0

array_3 = np.copy(array_2)
array_3 = np.roll(array_3,-1)
array_3[-1] = 0

result_1n2 = array_1-array_2
result_1n3 = array_1-array_3
result_last = array_1[0] - array_1[-1]

array_result = [result_1n2[0],result_1n3[0], result_last, result_1n2[1], result_1n3[1], result_1n2[2]]

print(array_result)

[-1, -2, -3, -1, -2, -1]

How should I approach this?

2
  • 1
    You might be better off using itertools.combinations. Commented Sep 25, 2020 at 20:34
  • I see, @Mad Physicist I will do that once I find the answer Commented Sep 25, 2020 at 21:04

2 Answers 2

7

numpy

At each element, you want to subtract off the elements that come after it. You can get the indices for this using np.trui_indices. The rest is just subtraction:

a, b = np.triu_indices(4, 1)
result = array_1[a] - array_1[b]

The second argument to triu_indices moves you up one diagonal. The default is 0, which includes the indices of the main diagonal:

>>> a
array([0, 0, 0, 1, 1, 2], dtype=int64)
>>> b
array([1, 2, 3, 2, 3, 3], dtype=int64)

>>> array_1[a]
array([1, 1, 1, 2, 2, 3])
>>> array_1[b]
array([2, 3, 4, 3, 4, 4])

>>> result
array([-1, -2, -3, -1, -2, -1])

If you ever need the input sorted by b instead of a, use np.tril_indices:

b, a = np.tril_indices(4, -1)

itertools

You can accomplish the same thing with itertools.combinations:

result = [a - b for a, b in itertools.combinations(array_1, 2)]

Wrap the result in an array if you want.

Sign up to request clarification or add additional context in comments.

5 Comments

Just try the itertools and that works perfect,thanks!
Also is there a way to give the result an identity? for instance, I can use loop to create a list of string [a-b, a-c, a-d,b-c,b-d,c-d] so result[0] is the difference between a&b. so when I process the result[x], I can go back the string[x] to know result[x] is the difference of which 2 element. Is there any module for this?
@WalkerCheung. Just look at the indices I used in my numpy solution. array_1[a[x]] is the first number and array_1[b[x]] the second.
@MadPhysicist the triu_indices approach seems to be much faster than itertools, thanks a lot for this answer
@SeanWilliam. Glad it helped. Generally, the only time python code will be faster than numpy is when you run out of memory
0

This is slightly different, but not as elegant as @Mad-Physicist 's answer. This uses broadcasting to get the differences.

import numpy as np
aa = np.arange(0,4,1);
bb = np.arange(4,8,1);
aa = aa[np.newaxis,:];
bb = bb[:,np.newaxis];
dd = aa - bb;
idx = np.triu_indices(4,1);
print(dd[idx])

1 Comment

Why bother computing all the possible combinations when you only need half of them?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.