有什么区别:
大熊猫 df.loc[:,('col_a','col_b')]
和
df.loc[:,['col_a','col_b']]
下面的链接没有提到后者,虽然它有效.拉两个视图?首先是拉视图而第二个是拉副本吗?喜欢学习熊猫.
http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
谢谢
unu*_*tbu 25
如果您的DataFrame有一个简单的列索引,那么没有区别.例如,
In [8]: df = pd.DataFrame(np.arange(12).reshape(4,3), columns=list('ABC'))
In [9]: df.loc[:, ['A','B']]
Out[9]:
A B
0 0 1
1 3 4
2 6 7
3 9 10
In [10]: df.loc[:, ('A','B')]
Out[10]:
A B
0 0 1
1 3 4
2 6 7
3 9 10
Run Code Online (Sandbox Code Playgroud)
但是如果DataFrame有一个MultiIndex,那么可能会有很大的不同:
df = pd.DataFrame(np.random.randint(10, size=(5,4)),
columns=pd.MultiIndex.from_arrays([['foo']*2+['bar']*2,
list('ABAB')]),
index=pd.MultiIndex.from_arrays([['baz']*2+['qux']*3,
list('CDCDC')]))
# foo bar
# A B A B
# baz C 7 9 9 9
# D 7 5 5 4
# qux C 5 0 5 1
# D 1 7 7 4
# C 6 4 3 5
In [27]: df.loc[:, ('foo','B')]
Out[27]:
baz C 9
D 5
qux C 0
D 7
C 4
Name: (foo, B), dtype: int64
In [28]: df.loc[:, ['foo','B']]
KeyError: 'MultiIndex Slicing requires the index to be fully lexsorted tuple len (1), lexsort depth (0)'
Run Code Online (Sandbox Code Playgroud)
KeyError表示MultiIndex必须是lexsorted.如果我们这样做,那么我们仍会得到不同的结果:
In [29]: df.sortlevel(axis=1).loc[:, ('foo','B')]
Out[29]:
baz C 9
D 5
qux C 0
D 7
C 4
Name: (foo, B), dtype: int64
In [30]: df.sortlevel(axis=1).loc[:, ['foo','B']]
Out[30]:
foo
A B
baz C 7 9
D 7 5
qux C 5 0
D 1 7
C 6 4
Run Code Online (Sandbox Code Playgroud)
这是为什么?df.sortlevel(axis=1).loc[:, ('foo','B')]
正在选择第一列级别等于的列foo
,第二列级别是B
.
相反,df.sortlevel(axis=1).loc[:, ['foo','B']]
选择第一列级别为foo
或的列B
.关于第一列级别,没有B
列,但有两foo
列.
我认为Pandas的操作原理是如果你df.loc[...]
用作表达式,你应该假设df.loc
可能正在返回一个副本或一个视图.Pandas文档没有指定您应该期望的任何规则.但是,如果您对表单进行了分配
df.loc[...] = value
Run Code Online (Sandbox Code Playgroud)
那么你可以信任熊猫改变df
自己.
文档警告视图和副本之间区别的原因是您了解使用表单链分配的缺陷
df.loc[...][...] = value
Run Code Online (Sandbox Code Playgroud)
在这里,Pandas df.loc[...]
首先评估,可能是视图或副本.现在,如果它是副本,那么
df.loc[...][...] = value
Run Code Online (Sandbox Code Playgroud)
正在改变某些部分的副本df
,因此对df
自身没有影响.为了增加对伤害的侮辱,对副本的影响也会丢失,因为没有对副本的引用,因此在赋值语句完成后无法访问副本,并且(至少在CPython中)它很快就会出现被垃圾收集.
我不知道一种实用的万无一失的先验方法来确定是否df.loc[...]
要返回视图或副本.
但是,有一些经验法则可能有助于指导您的直觉(但请注意,我们在这里讨论实现细节,因此无法保证Pandas将来需要以这种方式行事):
df.loc
可能再次返回副本.但是,有一种简单的方法可以确定x = df.loc[..]
视图是否为postiori:只需查看是否更改了值的x
影响df
.如果是,则视图(如果不是)x
是副本.