数据框iloc在熊猫中意外工作

时间:2019-05-10 05:32:42

标签: python pandas dataframe indexing

我正在创建这样的数据框。

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在做什么错,请帮忙。谢谢。

2 个答案:

答案 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