我需要从DataFrame的索引中删除一个级别(按位置或名称),并使用新索引创建一个新的DataFrame。问题是我最终得到了一个非唯一索引。
我看了Remove a level from a pandas MultiIndex,但问题是使用unique(),正如其中的答案所暗示的那样,减少了数组的索引,而不保留数组的名称。水平。
除了使用unique(),然后通过将标签名称拼接到数组上来创建新索引,是否有更优雅的解决方案?
index = [np.array(['foo', 'foo', 'qux']), np.array(['a', 'b', 'a'])]
data = np.random.randn(3, 2)
columns = ["X", "Y"]
df = pd.DataFrame(data, index=index, columns=columns)
df.index.names = ["Level0", "Level1"]
print df
X Y
Level0 Level1
foo a -0.591649 0.831599
b 0.049961 -1.524291
qux a -0.100124 -1.059195
index2 = df.reset_index(level=1, drop=True).index
df2 = pd.DataFrame(index=index2)
print df2.loc[idx['foo'], :]
Empty DataFrame
Columns: []
Index: [foo, foo]
答案 0 :(得分:1)
如果我理解正确,那么您正在寻找一种解决方案来获得没有重复值的第一级索引。您的结果应该是Ìndex
对象,而不使用unique
并且不再显式创建索引。
对于您的示例数据框,您可以使用以下内容,包括get_level_values
和drop_duplicates
:
print(df.index.get_level_values(0).drop_duplicates())
Index(['foo', 'qux'], dtype='object', name='Level0')
对于更一般的解决方案,要么根据级别数返回Index
或MultiIndex
,您可以结合使用droplevel
和drop_duplicates
:
print(df.index.droplevel(-1).drop_duplicates())
Index(['foo', 'qux'], dtype='object', name='Level0')
以下是来自链接SO帖子的示例,其中3个级别被降低到2级mutltiindex并具有唯一值:
tuples = [(0, 100, 1000),(0, 100, 1001),(0, 100, 1002), (1, 101, 1001)]
index_3levels=pd.MultiIndex.from_tuples(tuples,names=["l1","l2","l3"])
print(index_3levels)
MultiIndex(levels=[[0, 1], [100, 101], [1000, 1001, 1002]],
labels=[[0, 0, 0, 1], [0, 0, 0, 1], [0, 1, 2, 1]],
names=['l1', 'l2', 'l3'])
index2level= index_3levels.droplevel(-1).drop_duplicates()
print(index2level)
MultiIndex(levels=[[0, 1], [100, 101]],
labels=[[0, 1], [0, 1]],
names=['l1', 'l2'])
# show unique values of new index
print(index2level)
[(0, 100) (1, 101)]