Длина индекса Pandas DataFrame не соответствует количеству строк - PullRequest
0 голосов
/ 03 ноября 2018

У меня есть DataFrame с двумя уровнями MultiIndex: 'State' и 'RegionName' (если кто-либо завершил специализацию Applied Data Science for Python на Coursera, это последний проект первого класса).

Я пытаюсь превратить уровень 'RegionName' индекса в столбец DataFrame и использовать его для создания логической маски.

Я попробовал следующее:

housing_data['Town'] = housing_data.index.levels[1]

И я получаю ошибку: «Длина значений не соответствует длине индекса»

Я пытаюсь выяснить, как это возможно, потому что я буквально использую индекс DataFrame, чтобы добавить столбец к тому же DataFrame. Как длины могут не совпадать?

Если это добавляет дополнительную информацию:

np.shape(housing_data) returns (10730, 69)

len(housing_data.index) returns 10730

yet somehow len(housing_data.index.levels[1]) returns 8258

Может ли это быть частью моей проблемы?

Ответы [ 2 ]

0 голосов
/ 04 ноября 2018

TLDR; перейти к последней части (нет необходимости создавать новый столбец для логического маскирования в первую очередь!)

Теперь, чтобы ответить на ваш вопрос ...

В вашем DataFrame нет ничего плохого! С вашим подходом вы пропускаете только один шаг. Получение значений из .levels[] - это только первый шаг.

import pandas as pd
import numpy as np

iterables = [['bar', 'baz', 'foo', 'qux'], ['one', 'two']]
mult_index  = pd.MultiIndex.from_product(iterables, names=['first', 'second'])
df = pd.DataFrame(np.random.randn(8, 3), index=mult_index, columns=['A', 'B', 'C'])

mult_index # same as df.index

Будет выведено:

MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']],
           labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]],
           names=['first', 'second'])

Отсюда вы видите, что возврата значений levels недостаточно. Вы также должны отобразить эти значения на соответствующие значения labels. Длина labels будет равна количеству строк.

df['index_val1'] = [ mult_index.levels[0][i] for i in mult_index.labels[0]]

или

df['index_val1'] = [ df.index.levels[0][i] for i in df.index.labels[0]]

Для этого отображения есть встроенная функция!

df['index_val1'] = df.index.get_level_values(0)

На самом деле вы можете просто использовать get_level_values, чтобы выполнить все ваши логические маскировки. Нет необходимости создавать дополнительный столбец .

df[ df.index.get_level_values(0)=='bar']
0 голосов
/ 04 ноября 2018

Вы пробовали сброс?

df.reset_index(level=['RegionName'],inplace=True)
...