Попарные минимумы элементов Серии Панд - PullRequest
1 голос
/ 23 сентября 2019

Ввод:

numbers = pandas.Series([3,5,8,1], index=["A","B","C","D"])

A   3
B   5
C   8
D   1

Ожидаемый вывод (pandas DataFrame):

    A   B   C   D
A   3   3   3   1
B   3   5   5   1
C   3   5   8   1
D   1   1   1   1

Текущее (рабочее) решение:

pairwise_mins = pandas.DataFrame(index=numbers.index)

def calculate_mins(series, index):
    to_return = numpy.minimum(series, series[index])
    return to_return

for col in numbers.index:
    pairwise_mins[col] = calculate_mins(numbers, col)

Я подозреваю, что должно бытьлучшее, более короткое, векторизованное решение.Кто мог бы помочь мне с этим?

Ответы [ 3 ]

2 голосов
/ 23 сентября 2019

Используйте outer ufunc здесь, который обеспечивает numpy, в сочетании с numpy.minimum


n = numbers.to_numpy()

np.minimum.outer(n, n)

array([[3, 3, 3, 1],
       [3, 5, 5, 1],
       [3, 5, 8, 1],
       [1, 1, 1, 1]], dtype=int64)
2 голосов
/ 23 сентября 2019

Это можно сделать с помощью broadcasting:

pd.DataFrame(np.where(numbers.values[:,None] < numbers.values, 
                      numbers[:,None], 
                      numbers),
             index=numbers.index,
             columns=numbers.index)

Вывод:

   A  B  C  D
A  3  3  3  1
B  3  5  5  1
C  3  5  8  1
D  1  1  1  1
0 голосов
/ 23 сентября 2019

Используйте np.broadcast_to и np.clip

a = numbers.values
pd.DataFrame(np.broadcast_to(a, (a.size,a.size)).T.clip(max=a), 
                      columns=numbers.index, 
                      index=numbers.index)

Out[409]:
   A  B  C  D
A  3  3  3  1
B  3  5  5  1
C  3  5  8  1
D  1  1  1  1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...