DaraFrame 的赋值和切片

tricky

>>> df = pd.DataFrame(np.random.randn(4, 4),index = range(4), columns = list('ABCD'))
>>> df
A   B   C   D
0   -0.461282   0.535102    1.979702    -0.782241
1   -1.823763   0.769289    -1.246549   -0.718638
2   -0.028946   0.629081    0.242340    0.885860
3   -1.087284   0.363438    -0.309762   -0.989745

采用 [] index 的访问方法可以进行两列的交换

>>> df[['A','B']] = df[['B','A']]
>>> df
A   B   C   D
0   0.535102    -0.461282   1.979702    -0.782241
1   0.769289    -1.823763   -1.246549   -0.718638
2   0.629081    -0.028946   0.242340    0.885860
3   0.363438    -1.087284   -0.309762   -0.989745

然而使用 loc 和 iloc 进行相似的操作都是不行的

df.loc[:,['A','B']] = df.loc[:,['B','A']]
df
A   B   C   D
0   0.535102    -0.461282   1.979702    -0.782241
1   0.769289    -1.823763   -1.246549   -0.718638
2   0.629081    -0.028946   0.242340    0.885860
3   0.363438    -1.087284   -0.309762   -0.989745

这和 pandas 里对于 columns 和数据的绑定机制有关。此时应该这样

df.loc[:,['B', 'A']] = df[['A', 'B']].values
df
A   B   C   D
0   -0.461282   0.535102    1.979702    -0.782241
1   -1.823763   0.769289    -1.246549   -0.718638
2   -0.028946   0.629081    0.242340    0.885860
3   -1.087284   0.363438    -0.309762   -0.989745

对于 DataFrame 类型,作为左值和作为右值也不太一样,这和 numpy 中切片操作返回的 view 还是不一样的,numpy 中的 view 就是引用,无论作为 左值还是右值,都作为引用存在。前面已经演示了作为左值的情况,看看作为右值

作为右值的时候似乎返回一个数据副本

slc = df.loc[:,['A','B']]
slc
A   B
0   -0.461282   0.535102
1   -1.823763   0.769289
2   -0.028946   0.629081
3   -1.087284   0.363438
slc.loc[:,['A']] = 1
slc
A   B
0   1.0 0.535102
1   1.0 0.769289
2   1.0 0.629081
3   1.0 0.363438
df
A   B   C   D
0   -0.461282   0.535102    1.979702    -0.782241
1   -1.823763   0.769289    -1.246549   -0.718638
2   -0.028946   0.629081    0.242340    0.885860
3   -1.087284   0.363438    -0.309762   -0.989745

此时不影响 df 本身,但是不能直接对 df 赋值,否则会这样

df =  1
df
1

对所有元素赋值应该采用全部切片

df = pd.DataFrame(np.random.randn(4, 4),index = range(4), columns = list('ABCD'))
df.iloc[:] = 1
df
A   B   C   D
0   1.0 1.0 1.0 1.0
1   1.0 1.0 1.0 1.0
2   1.0 1.0 1.0 1.0
3   1.0 1.0 1.0 1.0

另外,对 DataFrame 的操作最好不要使用链式选择

# not advised
df['A', 'B']['A']

#RIGHT
df['A']