python数据框索引_python – 在数据框中从多索引中完全删除一个索引标签

鉴于我有这个多索引数据帧:

>>> import pandas as p

>>> import numpy as np

...

>>> arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo']),

... np.array(['one', 'two', 'one', 'two', 'one', 'two'])]

...

>>> s = p.Series(np.random.randn(6), index=arrays)

>>> s

bar one -1.046752

two 2.035839

baz one 1.192775

two 1.774266

foo one -1.716643

two 1.158605

dtype: float64

我应该如何消除索引栏?

我试着用滴

>>> s1 = s.drop('bar')

>>> s1

baz one 1.192775

two 1.774266

foo one -1.716643

two 1.158605

dtype: float64

看起来不错,但酒吧仍然以某种奇怪的方式存在:

>>> s1.index

MultiIndex(levels=[[u'bar', u'baz', u'foo'], [u'one', u'two']],

labels=[[1, 1, 2, 2], [0, 1, 0, 1]])

>>> s1['bar']

Series([], dtype: float64)

>>>

我怎么能从这个索引标签中获取任何残留物?

解决方法:

绝对看起来像一个bug.

s1.index.tolist()返回没有“bar”的期望值.

>>> s1.index.tolist()

[('baz', 'one'), ('baz', 'two'), ('foo', 'one'), ('foo', 'two')]

s1 [“bar”]返回null系列.

>>> s1["bar"]

Series([], dtype: float64)

覆盖它的标准方法似乎也不起作用:

>>> del s1["bar"]

>>> s1["bar"]

Series([], dtype: float64)

>>> s1.__delitem__("bar")

>>> s1["bar"]

Series([], dtype: float64)

但是,正如预期的那样,尝试获取新密钥会调用KeyError:

>>> s1["booz"]

... KeyError: 'booz'

主要区别在于你实际查看pandas.core.index.py中两者之间的源代码

class MultiIndex(Index):

...

def _get_levels(self):

return self._levels

...

def _get_labels(self):

return self._labels

# ops compat

def tolist(self):

"""

return a list of the Index values

"""

return list(self.values)

因此,index.tolist()和_labels不访问同一条共享信息,事实上,它们甚至都没有接近.

因此,我们可以使用它来手动更新生成的索引器.

>>> s1.index.labels

FrozenList([[1, 1, 2, 2], [0, 1, 0, 1]])

>>> s1.index._levels

FrozenList([[u'bar', u'baz', u'foo'], [u'one', u'two']])

>>> s1.index.values

array([('baz', 'one'), ('baz', 'two'), ('foo', 'one'), ('foo', 'two')], dtype=object)

如果我们将它与最初的多索引索引进行比较,我们得到

>>> s.index.labels

FrozenList([[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]])

>>> s.index._levels

FrozenList([[u'bar', u'baz', u'foo'], [u'one', u'two']])

所以_levels属性不会更新,而值是.

编辑:覆盖它并不像我想象的那么容易.

编辑:写了一个自定义函数来解决这个问题

from pandas.core.base import FrozenList, FrozenNDArray

def drop(series, level, index_name):

# make new tmp series

new_series = series.drop(index_name)

# grab all indexing labels, levels, attributes

levels = new_series.index.levels

labels = new_series.index.labels

index_pos = levels[level].tolist().index(index_name)

# now need to reset the actual levels

level_names = levels[level]

# has no __delitem__, so... need to remake

tmp_names = FrozenList([i for i in level_names if i != index_name])

levels = FrozenList([j if i != level else tmp_names

for i, j in enumerate(levels)])

# need to turn off validation

new_series.index.set_levels(levels, verify_integrity=False, inplace=True)

# reset the labels

level_labels = labels[level].tolist()

tmp_labels = FrozenNDArray([i-1 if i > index_pos else i

for i in level_labels])

labels = FrozenList([j if i != level else tmp_labels

for i, j in enumerate(labels)])

new_series.index.set_labels(labels, verify_integrity=False, inplace=True)

return new_series

示例用户:

>>> s1 = drop(s, 0, "bar")

>>> s1.index

MultiIndex(levels=[[u'baz', u'foo'], [u'one', u'two']],

labels=[[0, 0, 1, 1], [0, 1, 0, 1]])

>>> s1.index.tolist()

[('baz', 'one'), ('baz', 'two'), ('foo', 'one'), ('foo', 'two')]

>>> s1["bar"]

...

KeyError: 'bar'

编辑:这似乎特定于具有多索引的数据帧/系列,因为标准的pandas.core.index.Index类没有相同的限制.我建议提交错误报告.

考虑具有标准索引的相同系列:

>>> s = p.Series(np.random.randn(6))

>>> s.index

Int64Index([0, 1, 2, 3, 4, 5], dtype='int64')

>>> s.drop(0, inplace=True)

>>> s.index

Int64Index([1, 2, 3, 4, 5], dtype='int64')

对于数据帧也是如此

>>> df = p.DataFrame([np.random.randn(6), np.random.randn(6)])

>>> df.index

Int64Index([0, 1], dtype='int64')

>>> df.drop(0, inplace=True)

>>> df.index

Int64Index([1], dtype='int64')

标签:python,pandas,multi-index

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值