np.subtract.outer () возвращает больше измерений, чем я ожидаю

У меня есть dataframe, который индексируется по дате и имеет четыре столбца, все целые числа.

Моя конечная цель – создать еще один фрейм данных, который также индексирует по дате и вместо четырех столбцов скалярных значений, представляет собой массив 4×4, который имеет все комбинации различий между значениями четырех столбцов в эту дату.

ABCD 1/1/2013 7 -1 1 2 

Я бы хотел создать массив 2d, который выглядит так:

  ABCD 7 -1 1 2 A 7 0 8 6 5 B -1 -8 0 -2 -3 C 1 -6 2 0 -1 D 2 -5 3 1 0 

где значения данных представляют собой комбинации различий между значениями столбцов.

Затем я сделаю этот 2d-массив для каждой даты в исходном фрейме данных

Я пытался сделать это «pythonically / panda-ly» без грубых циклов и вещей.

Я сделал простейший случай – исходная датафрейм имеет только одну строку данных:

 ddf is type <class 'pandas.core.frame.DataFrame'>, shape (1, 4) ABCD 2013-01-02 7 -1 1 2 

Я кормлю это ddf в

 def makeRelativeChangeDF(deltaDF): """return array wit all the combinations of differences between columns""" return np.subtract.outer(deltaDF, deltaDF) 

Это возвращает:

 rcdf is type <class 'pandas.core.frame.DataFrame'>, shape (1, 4) [[[[ 0. 8. 6. 5.]] [[-8. 0. -2. -3.]] [[-6. 2. 0. -1.]] [[-5. 3. 1. 0.]]]] 

Не уверен, почему это дает странную форму (1,4). Я ожидал (4,4). И, глядя на распечатку rcdf, я вижу, что он сильно обернут множеством массивов. Наверное, я неправильно использую внешнюю функцию. Я хотел бы сделать это правильно, чем использовать уродливые перетаскивающие хаки, чтобы вытащить (исправить) данные, но переупаковать их в правильной форме.

Вы можете преобразовать двумерный входной кадр в 1D-серию, выбрав первую строку с .iloc[0] а затем используйте np.subtract.outer() , например:

 np.subtract.outer(deltaDF.iloc[0],deltaDF.iloc[0]) 

Кажется, вы также можете использовать broadcasting

 deltaDF.iloc[0][:,None] - deltaDF.iloc[0][None,:] 

Пример прогона –

 In [107]: type(deltaDF) Out[107]: pandas.core.frame.DataFrame In [108]: np.subtract.outer(deltaDF.iloc[0],deltaDF.iloc[0]) Out[108]: array([[ 0, 8, 6, 5], [-8, 0, -2, -3], [-6, 2, 0, -1], [-5, 3, 1, 0]]) In [109]: deltaDF.iloc[0][:,None] - deltaDF.iloc[0][None,:] Out[109]: array([[ 0, 8, 6, 5], [-8, 0, -2, -3], [-6, 2, 0, -1], [-5, 3, 1, 0]])