Как я могу ссылаться на индекс моего фрейма данных Pandas?
у меня есть фрейм данных 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 ответов
Я думаю, у вас есть небольшое недопонимание того, что такое индексы. Вы не просто "назначаете" столбцы индексами; то есть вы не просто "помечаете" определенные столбцы информацией, которая говорит "это индекс". Индекс-это отдельная структура данных, которая может содержать данные, которые не присутствуют в Столбцах. Если вы это сделаете set_index
, вы движение эти столбцы в индекс, поэтому они больше не существуют как обычные столбцы. Вот почему вы больше не можете использовать их так, как упоминаете: они их больше нет.
одна вещь, которую вы можете сделать, это при использовании set_index
, передать drop=False
чтобы сказать ему сохранить столбцы как столбцы в дополнение к помещению их в индекс (эффективно копируя их в индекс, а не перемещая их), например, df.set_index('SomeColumn', drop=False)
. Однако вы должны знать, что индекс и столбец по-прежнему различны, поэтому, например, если вы измените значения столбцов, это не повлияет на то, что хранится в индексе.
в результате получается, что индексы на самом деле не столбцы фрейма данных, поэтому, если вы хотите использовать некоторые данные как индекс, так и столбец, вам нужно дублировать их в обоих местах. Существует некоторое обсуждение этого вопроса здесь.
информация доступна с помощью индекса 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'))
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. Одно из золотых правил проектирования баз данных, "никогда не повторяйте одни и те же данные в двух местах" так рано или позже данные станут непоследовательными и, таким образом, поврежденными. Поэтому я бы рекомендовал против сохранение данных как столбца, так и индекса, в первую очередь потому, что это может привести к повреждению данных, а также потому, что это может быть неэффективное использование памяти.