具有单独索引的数据框列

Vla*_*kow 14 python indexing dataframe pandas

我注意到一个有趣的行为,我在文档中没有看到:

数据框中每一列都可以有其单独的索引!

df = pd.DataFrame(np.arange(12).reshape(4, 3, order='F'),
                  columns=list('abc'))

df
   a  b   c
0  0  4   8
1  1  5   9
2  2  6  10
3  3  7  11
Run Code Online (Sandbox Code Playgroud)

将索引分配给列b

df['b'].index = [-1, 2, 4, 5]
Run Code Online (Sandbox Code Playgroud)

不同列的索引不同,但它们都共享相同的数据帧索引:

df['a']
0    0
1    1
2    2
3    3
Name: a, dtype: int64

df['b']
-1    4
 2    5
 4    6
 5    7
Name: b, dtype: int64


df.loc[:2, ['b']]
   b
0  4
1  5
2  6

df.loc[:2, 'b']
-1    4
 2    5
Name: b, dtype: int64
Run Code Online (Sandbox Code Playgroud)

文档中是否对此进行了描述?

首先为什么可以做到这一点?这对某些事情有用吗?

小智 3

文档中是否对此进行了描述?

仔细查看文档后,似乎并非如此。

首先为什么可以做到这一点?

看来是因为缓存的存在。如果我以你的例子为例:

df = pd.DataFrame(np.arange(12).reshape(4, 3, order='F'),
                  columns=list('abc'))
>>> df
    a   b   c
0   0   4   8
1   1   5   9
2   2   6   10
3   3   7   11

>>> df._item_cache
{}
Run Code Online (Sandbox Code Playgroud)

起初,缓存是空的。如果您只是访问一列,该系列将被缓存。

>>> df['a']
0    0
1    1
2    2
3    3
Name: a, dtype: int32

>>> df._item_cache
{'a': 0    0
 1    1
 2    2
 3    3
 Name: a, dtype: int32}
Run Code Online (Sandbox Code Playgroud)

假设我们更改了系列“b”的索引,所以现在缓存如下所示。

df['b'].index = [-1, 2, 4, 5]

>>> df._item_cache
{'a': 0    0
 1    1
 2    2
 3    3
 Name: a, dtype: int32,
 'b': -1    4
  2    5
  4    6
  5    7
 Name: b, dtype: int32}
Run Code Online (Sandbox Code Playgroud)

当您通过 DataFrame 访问列“b”时__getitem__(),它的工作原理如下。

key = 'b'
df._get_item_cache(key)
Run Code Online (Sandbox Code Playgroud)

具体来说,在源码中,由于'b'是可哈希类型,所以会返回实际系列的缓存。如果类型不可散列(例如列表['b']),那么它将首先进行复制,并使缓存变得无关紧要。

当您使用 .loc 时__getitem__(),它的工作方式有点不同。但本质上,它使用缓存索引提取该系列。然而,不太确定为什么['b']在这种情况下会显示 df 索引......这方面还有更多的挖掘工作要做。

这对某些事情有用吗?

可能不会。我想,虽然它可以用作数据的第三个维度,但我相信还有其他更实用的解决方案。