Python: как изменить форму данных путем суммирования соседних ячеек? - PullRequest
0 голосов
/ 21 марта 2019

Я сгенерировал фрейм данных df из матрицы.

M=np.random.randint(10, size=(7, 5))
df = pd.DataFrame(M)
df  
        0   1   2   3   4
     0  8   3   2   2   5
     1  5   8   1   5   6
     2  1   9   1   4   2
     3  0   7   7   6   9
     4  5   8   7   0   9
     5  0   3   9   9   4
     6  7   7   8   5   4

Я хотел бы создать новый фрейм данных df1 путем суммирования соседних ячеек 3x3 из df.

### Aggregate rows 0,1,2 and columns 0,1,2
df1[0][0] = [8+3+2+5+8+1+1+9+1] = 38
### Aggregate rows 0,1,2 and columns 2,3,4
df1[1][0] = [2+2+5+1+5+6+1+4+2] = 28

### Aggregate rows 2,3,4 and columns 0,1,2
df1[1][0] = [1+9+1+0+7+7+5+8+7] = 45
### Aggregate rows 2,3,4 and columns 2,3,4
df1[1][1] = [1+4+2+7+6+9+7+0+9] = 45

### Aggregate rows 4,5,6 and columns 0,1,2
df1[2][0] = [5+8+7+0+3+9+7+7+8] = 55
### Aggregate rows 4,5,6 and columns 2,3,4
df1[2][1] = [7+0+9+9+9+4+8+5+4] = 55


df1    
        0    1
    0  38   28
    1  45   45
    2  55   55

Ответы [ 2 ]

2 голосов
/ 21 марта 2019

Вы можете сделать это с помощью свертки с функцией convolve2d в scipy:

M = np.random.randint(10, size=(7, 5))
print(M)

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


from scipy.signal import convolve2d

r = convolve2d(M, np.ones([3,3]), mode='same')[1::2,1::2]
print(r)

[[41. 42.]
 [46. 45.]
 [42. 43.]]

Здесь np.ones([3,3]) генерирует маску, матрицу 3х3 из них:

array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])

И я использую индексирование [1 :: 2, 1 :: 2], чтобы начать с элемента 1 вместо 0 и пропустить все остальные строки / столбцы, как это делается в вопросе.

Также см. Получение суммы смежных элементов матрицы для получения дополнительной информации

0 голосов
/ 21 марта 2019

Вы можете сделать это с помощью df.shift

axes = (0, 1)
shifts = -1, 1
intermediate_sum = (
    df
    + sum(df.shift(shift, axis=axis) for shift, axis in product(shifts, axes))
)
result = (
    intermediate_sum.dropna(how="all", axis=0)
    .dropna(how="all", axis=1)
    .iloc[::2, ::2]
)
result
  1   3
1 23.0    22.0
3 35.0    33.0
5 18.0    18.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...