我如何参考我的Pandas数据帧的索引?

oro*_*ome 8 python indexing dataframe pandas

我有一个Pandas数据框,我已将一些列指定为索引:

planets_dataframe.set_index(['host','name'], inplace=True)
Run Code Online (Sandbox Code Playgroud)

并希望能够在各种情况下参考这些指数.使用索引的名称在查询中工作正常

planets_dataframe.query('host == "PSR 1257 12"')
Run Code Online (Sandbox Code Playgroud)

但如果尝试使用它来获取索引值的列表,则会导致错误,因为它是一个列

planets_dataframe.name
#AttributeError: 'DataFrame' object has no attribute 'name'
Run Code Online (Sandbox Code Playgroud)

或者用它来列出结果,因为它是"常规"列

planets_dataframe.query('30 > mass > 20 and discoveryyear > 2009')['name']
#KeyError: u'no item named name'
Run Code Online (Sandbox Code Playgroud)

如何引用我用作索引的数据框的"列"?


之前set_index:

planets_dataframe.columns
# Index([u'name', u'lastupdate', u'temperature', u'semimajoraxis', u'discoveryyear', u'calculated', u'period', u'age', u'mass', u'host', u'verification', u'transittime', u'eccentricity', u'radius', u'discoverymethod', u'inclination'], dtype='object')
Run Code Online (Sandbox Code Playgroud)

之后set_index:

planets_dataframe.columns
#Index([u'lastupdate', u'temperature', u'semimajoraxis', u'discoveryyear', u'calculated', u'period', u'age', u'mass', u'verification', u'transittime', u'eccentricity', u'radius', u'discoverymethod', u'inclination'], dtype='object')
Run Code Online (Sandbox Code Playgroud)

Bre*_*arn 16

我认为你对索引有一点误解.您不只是将"指定"列作为索引; 也就是说,您不仅仅使用"这是一个索引"的信息"标记"某些列.索引是一个单独的数据结构,可以保存列中甚至不存在的数据.如果这样做set_index,则将这些列移动到索引中,因此它们不再作为常规列存在.这就是为什么你不能再以你提到的方式使用它们了:它们不再存在了.

你可以做的一件事是,在使用时set_index,传递drop=False告诉它将列保持为列除了将它们放入索引(有效地将它们复制到索引而不是移动它们),例如,df.set_index('SomeColumn', drop=False).但是,您应该知道索引和列仍然是不同的,因此,例如,如果您修改列值,这将不会影响索引中存储的内容.

结果是索引不是DataFrame的真正列,因此如果您希望能够将某些数据用作索引和列,则需要在两个位置复制它.有这个问题的一些讨论在这里.


unu*_*tbu 5

可以使用索引的get_level_values方法访问该信息:

import numpy as np
import pandas as pd
np.random.seed(1)

df = pd.DataFrame(np.random.randint(4, size=(10,4)), columns=list('ABCD'))    
idf = df.set_index(list('AB'))
Run Code Online (Sandbox Code Playgroud)

idf.index.get_level_values('A')大致等于df['A']。但是请注意type和dtype的更改:

print(df['A'])
# 0    1
# 1    3
# 2    3
# 3    0
# 4    2
# 5    2
# 6    3
# 7    1
# 8    3
# 9    3
# Name: A, dtype: int32

def level(df, lvl):
    return df.index.get_level_values(lvl)

print(level(idf, 'A'))
# Int64Index([1, 3, 3, 0, 2, 2, 3, 1, 3, 3], dtype='int64')
Run Code Online (Sandbox Code Playgroud)

同样,在这里['A'],您可以使用来获取等效信息.index.get_level_values('A')

print(df.query('3>C>0 and D>0')['A'])
# 8    3
# Name: A, dtype: int32

print(level(idf.query('3>C>0 and D>0'), 'A'))
# Int64Index([3], dtype='int64')
Run Code Online (Sandbox Code Playgroud)

PS。数据库设计的黄金法则之一是“永远不要在两个地方重复相同的数据”,因为数据迟早会变得不一致并因此被破坏。因此,我建议不要同时将数据保留为列和索引,这主要是因为它可能导致数据损坏,还因为它可能导致内存使用效率低下。