Нахождение среднего значения соседних элементов (строки и столбца) в DataFrame - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть изображение, из которого я создал DataFrame на основе его интенсивности пикселей.Исходя из этого, я хотел бы создать сетку, в которой я нахожу среднюю интенсивность внутри каждого квадрата в этой сетке, представленную 2x2 пикселя.Это будет сделано для того, чтобы охватить большие области интенсивностей, чтобы отличить их от фонового шума.(Я подумал, что было бы неплохо включить это для обеспечения контекста.)

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

Итак, чтобы проиллюстрировать проблему, допустим, у нас есть следующий DataFrame:

df=pd.DataFrame({'A':(np.linspace(1,4,num=4)),'B':(np.linspace(5,8,num=4)),'C':(np.linspace(9,12,num=4)), 'D':(np.linspace(13,16,num=4))})

Исходя из этого, мы хотим создать DataFrame, который соответствует среднему значению каждого квадрата.В этом случае это будет соответствовать следующему (то есть, например, 3 будет средним квадратом 2x2 со значениями (1,5,2,6), 11,5 будет средним значением (9, 13, 10,14):

df_mean=DataFrame({'A':pd.Series([3,11.5]),'B':pd.Series([5.5,13.5])})

Если вопрос по-прежнему неясен, представьте, что вы берете оригинальный DataFrame и рисуете вертикальную линию и горизонтальную линию посередине. Таким образом, вы получите 4 блока. Внутри каждого из 4 блоковВы найдете 4 значения. Я хотел бы рассчитать среднее значение для каждого блока и вставить его в новый DataFrame, который состоит из средств блоков.

PS: К сожалению, я пока не знаю, как отобразитьСами DataFrames, а не просто код. Функция печати не сработала. Надеюсь, это не слишком утомительно.

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Просто используйте свертку для нижележащего массива:

import scipy.ndimage
full_conv = scipy.ndimage.filters.convolve(df.values, 0.25*np.ones((2,2)))
strided_conv = full_conv[::2, ::2]

Результат:

array([[ 3.5, 11.5],
       [ 5.5, 13.5]])
0 голосов
/ 12 сентября 2018

Вы можете сделать это очень эффективно, используя базовый массив numpy:

def square_mean(arr, y, x):
    yy, xx = arr.shape
    vals = arr.reshape(y, yy//y, x, xx//x).mean((1,3))
    return vals

pd.DataFrame(square_mean(df.values, 2, 2))

     0     1
0  3.5  11.5
1  5.5  13.5

Это решение работает из-за некоторого умного изменения формы массиваВот как работает изменение формы:

yy, xx = arr.shape
vals = arr.reshape(2, yy//2, 2, xx//2)
print(vals)

[[[[ 1.  5.]
   [ 9. 13.]]

  [[ 2.  6.]
   [10. 14.]]]


 [[[ 3.  7.]
   [11. 15.]]

  [[ 4.  8.]
   [12. 16.]]]]

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


Это решение масштабируется до всех входных размеров, просто выберите x в качестве количества чанков вдоль оси x и y в качестве количества чанков вдоль оси y:

df = pd.DataFrame(np.random.randint(1, 5, (10, 10)))

   0  1  2  3  4  5  6  7  8  9
0  1  3  4  2  3  3  3  2  1  2
1  3  3  4  1  3  4  4  4  1  3
2  2  3  2  2  4  4  1  1  1  1
3  1  2  1  2  1  3  1  1  2  3
4  2  2  3  4  3  2  4  3  4  2
5  3  3  1  4  2  1  2  3  1  3
6  2  1  3  4  3  2  3  4  3  4
7  2  3  4  2  1  1  1  1  3  2
8  4  3  2  2  2  2  2  1  3  3
9  3  2  1  2  1  3  4  2  4  4

Мы можем разделить на любое количество кусков:

square_mean(df.values, 2, 2)

array([[2.44, 2.4 ],
       [2.4 , 2.48]])

square_mean(df.values, 5, 5)

array([[2.5 , 2.75, 3.25, 3.25, 1.75],
       [2.  , 1.75, 3.  , 1.  , 1.75],
       [2.5 , 3.  , 2.  , 3.  , 2.5 ],
       [2.  , 3.25, 1.75, 2.25, 3.  ],
       [3.  , 1.75, 2.  , 2.25, 3.5 ]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...