我正在创建这样的数据框。
np.random.seed(2)
df=pd.DataFrame(np.random.randint(1,6,(6,6)))
out[]
0 1 1 4 3 4 1
1 3 2 4 3 5 5
2 5 4 5 3 4 4
3 3 2 3 5 4 1
4 5 4 2 3 1 5
5 5 3 5 3 2 1
将数据帧分成3,3矩阵,如下所示,它将有16个矩阵。 dfs = []
for col in range(df.shape[1]-2):
for row in range(df.shape[0]-2):
dfs.append(df.iloc[row:row+3,col:col+3])
让打印
dfs[0]
1 1 4
3 2 4
5 4 5
dfs[1]
3 2 4
5 4 5
3 2 3
.
.
.
dfs[15]
5 4 1
3 1 5
3 2 1
编写一个函数,将位置[1,0]和[1,2]中每个矩阵的值更改为零, 这样我的输出看起来就像
dfs[0]
1 1 4
0 2 0
5 4 5
def process(x):
new=[]
for d in x:
d.iloc[1,0]=0
d.iloc[1,2]=0
new.append(d)
print(d)
return new
dfs=process(dfs.copy())
我的预期输出是
dfs[0]
1 1 4
0 2 0
5 4 5
但是我的函数返回的是
dfs[0]
1 1 4
0 0 0
0 0 0
dfs[1]
0 0 0
0 0 0
0 0 0
在所有矩阵中产生更多的零。我不知道为什么它无法正常工作,或者我的函数process
在做什么错,请帮忙。谢谢。
答案 0 :(得分:2)
更改代码和process
函数调用以获取所需的输出。另外,我使用了copy in for循环来制作数据帧的子集,该子集与将来的更改无关,在您的情况下,它将对原始df进行更改,并以其他dfs列表中的全零反映出来:
for col in range(df.shape[1]-2):
for row in range(df.shape[0]-2):
dfs.append(df.iloc[row:row+3,col:col+3].copy())
dfs=process(dfs)
答案 1 :(得分:2)
长话短说,您是chained indexing(可以lead to bad things happening)的受害者。
切片原始DataFrame
时,会得到重叠的视图。
修改一个对象也会改变其他对象,因为一个块的第二行是另一个块的第一行,第一个块的第三行是另一个块的第一行,依此类推...这就是为什么只能在“边缘”看到非零值,因为它们对于单个块是唯一的。
您可以像这样复制每个切片:
def process(x):
new = []
for d in x:
d = d.copy() # each one is now a copy
d.iloc[1, 0]=0
d.iloc[1, 2]=0
new.append(d)
return new
最后,请注意,dfs = process(dfs)
实际上很好;您无需复制随附的list
。