Python:如何通过对相邻单元格求和来重塑数据帧?

Python:如何通过对相邻单元格求和来重塑数据帧?,python,pandas,numpy,group-by,Python,Pandas,Numpy,Group By,我已经从一个矩阵生成了一个数据帧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

我已经从一个矩阵生成了一个数据帧
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
我想通过对
df
的相邻单元格
3x3
求和来生成一个新的数据帧
df1

### 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

您可以使用
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

您可以使用
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

您可以使用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])
生成掩码,3x3个一的矩阵:

array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
我使用[1::2,1::2]索引从元素1开始,而不是从0开始,并像在问题中一样跳过每一行/列


有关更多信息,请参见

,您可以在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])
生成掩码,3x3个一的矩阵:

array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
我使用[1::2,1::2]索引从元素1开始,而不是从0开始,并像在问题中一样跳过每一行/列


另请参见了解更多信息,以澄清:每次求和都会跳过一行一列?@MarcusLim在我的例子中,我有一个矩阵103 x 159,我必须找到一个解决方案来聚合这些值。在这种情况下,我跳过两行两列的每个和,我觉得应该有一些方法。看起来像一个简单的卷积来澄清:每个和,你跳过一行一列?@MarcusLim在我的情况下,我有一个矩阵103 x 159,我必须找到一个解决方案来聚合这些值。在这种情况下,每个和我跳过两行和两列,加上标记numpy,我觉得应该有一些方法来解决这个问题。看起来像是一个简单的卷积。我得到了以下结果:
AxisError:axis1超出了维度1数组的界限,当我试图计算
中间值时,结果与预期不同?@RafaelC随机数是生成的,没有设置种子。参见OP的顶行。我得到以下信息:
AxisError:当我试图计算
中间值和时,轴1超出维度1数组的界限
,结果与预期不同?@RafaelC生成随机数,没有设置种子。看《凤凰社》的头条。这正是我要找的。一个问题:为什么有
np.ones([3,3])
np.ones([3,3])
生成掩码,3x3矩阵1',这正是我想要的。一个问题:为什么有
np.one([3,3])
np.one([3,3])
生成掩码,3x3矩阵1