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

时间:2014-04-26 17:51:09

标签: python pandas indexing dataframe

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

planets_dataframe.set_index(['host','name'], inplace=True)

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

planets_dataframe.query('host == "PSR 1257 12"')

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

planets_dataframe.name
#AttributeError: 'DataFrame' object has no attribute 'name'

或使用它来列出结果,因为它是“常规”列

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

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


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')

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')

2 个答案:

答案 0 :(得分:14)

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

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

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

答案 1 :(得分:3)

可以使用索引get_level_values method

访问该信息
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'))

idf.index.get_level_values('A')大致相当于df['A']。但请注意类型和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')

再次在这里,您可以使用['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')

PS。数据库设计的一个重要规则是“永远不要在两个地方重复相同的数据”,因为数据迟早会变得不一致并因此被破坏。所以我建议反对将数据保持为列和索引,主要是因为它可能导致数据损坏,但也因为它可能是对内存的低效使用。