2014-01-08 2 views
5

Ищет советы о том, как написать функцию (или можно рекомендовать функцию, которая уже существует), которая вычисляет разницу между всеми элементами массива, то есть реализацией diff(), но для всех комбинаций записей в массиве не только последовательные пары.Разница между всеми 1D точками в массиве с python diff()?

Вот пример того, что я хочу:

# example array 
a = [3, 2, 5, 1] 

Теперь мы хотим применить функцию, которая будет возвращать разницу между всеми комбинациями записей. Теперь, учитывая, что length(a) == 4 означает, что общее количество комбинаций для N = 4; N * (N-1) * 0,5 = 6 (если длина a равна 5, то общее количество комбинаций будет равно 10 и так далее). Таким образом, функция должна возвращать следующее для вектора a:

result = some_function(a) 
print result 
array([-1, 2, -2, 3, -1, -4]) 

Так «функция» будет похожа на pdist но вместо вычисления расстояния Евклида, он должен просто вычислить разницу между декартова координата вдоль одной оси, например, ось z, если предположить, что элементы в a являются координатами. Как можно заметить, мне нужен знак каждой разницы, чтобы понять, на какой стороне оси расположена каждая точка.

Спасибо.

ответ

4

Что-то вроде этого?

>>> import itertools as it 
>>> a = [3, 2, 5, 1] 
>>> [y - x for x, y in it.combinations(a, 2)] 
[-1, 2, -2, 3, -1, -4] 
+0

Приветствия. Да что-то в этом роде. Но мне было интересно, есть ли функция numpy или scipy, которая делает это эффективно? Мне нужно вычислить приведенное выше для нескольких десятков тысяч строк данных, поэтому в идеале оно должно быть эффективным. – Astrid

+4

@Astrid - векторная версия numpy будет вычислять каждое значение дважды, но в некоторых случаях она может быть еще быстрее. В принципе, вам нужен нижний треугольник 'np.subtract.outer (a, a)'. Тем не менее, ответ wim скорее всего будет быстрее во многих случаях. –

+0

@JoeKington - Хорошо, я сделаю некоторые эксперименты и посмотрю, что я придумал. Благодарю. – Astrid

1

Так что я опробовал методы, предложенные WIM и Джо (и Джо и Вима в сочетании внушение), и это то, что я придумал:

import itertools as it 
import numpy as np 

a = np.random.randint(10, size=1000) 

def cartesian_distance(x): 
    return np.subtract.outer(x,x)[np.tril_indices(x.shape[0],k=-1)] 

%timeit cartesian_distance(a) 
%timeit [y - x for x, y in it.combinations(a, 2)] 

10 loops, best of 3: 97.9 ms per loop 
1 loops, best of 3: 333 ms per loop 

Для более мелкие записи:

a = np.random.randint(10, size=10) 

def cartesian_distance(x): 
    return np.subtract.outer(x,x)[np.tril_indices(x.shape[0],k=-1)] 

%timeit cartesian_distance(a) 
%timeit [y - x for x, y in it.combinations(a, 2)] 

10000 loops, best of 3: 78.6 µs per loop 
10000 loops, best of 3: 40.1 µs per loop 
Смежные вопросы