Срез Dataframe не удаляет значения индекса
1346 просмотра
3 ответа
У меня недавно была эта проблема с большим фреймом данных и связанным с ним мультииндексом. Этот упрощенный пример продемонстрирует проблему.
import pandas as pd
import numpy as np
np.random.seed(1)
idx = pd.MultiIndex.from_product([['A','B'],[5,6]])
df = pd.DataFrame(data= np.random.randint(1,100,(4)),index= idx,columns =['P'])
print df
Который дает:
P
A 5 38
6 13
B 5 73
6 10
Теперь взглянем на индекс
print df.index
MultiIndex(levels=[[u'A', u'B'], [5, 6]],
labels=[[0, 0, 1, 1], [0, 1, 0, 1]])
Если я нарежу этот фрейм данных, я замечу, что мультииндекс никогда не сгущается. Даже с глубокой копией.
Каков наилучший способ уменьшить объем памяти индекса в операции среза?
df_slice = df[df['P']>20]
print df_slice
print df_slice.index
P
A 5 38
B 5 73
Посмотрите, как уменьшился размер информационного кадра, а индекс - нет.
MultiIndex(levels=[[u'A', u'B'], [5, 6]],
labels=[[0, 1], [0, 0]])
Даже с копией (глубокий = True)
df_slice = df[df['P']>20].copy(deep=True)
print df_slice.index
MultiIndex(levels=[[u'A', u'B'], [5, 6]]
,labels=[[0, 1], [0, 0]])
Я бы ожидал, что MultiIndex удалит 6, как показано:
MultiIndex(levels=[[u'A', u'B'], [5]]
,labels=[[0, 1], [0, 0]])
Проблема возникает на практике, когда размер кадра данных велик.
Автор: Dickster Источник Размещён: 12.11.2019 09:54Ответы (3)
4 плюса
Я понимаю вашу озабоченность, но я считаю, что вы должны видеть, что происходит в приложениях низкого уровня для панд.
Во-первых, мы должны объявить, что индексы должны быть неизменными. Вы можете проверить больше документации здесь -> http://pandas.pydata.org/pandas-docs/stable/indexing.html#setting-metadata
Когда вы создаете объект dataframe, давайте назовем его, df
и вы захотите получить доступ к его строкам, в основном все, что вы делаете, это передаете логический ряд, который Pandas будет сопоставлять с соответствующим индексом.
Следуйте этому примеру:
index = pd.MultiIndex.from_product([['A','B'],[5,6]])
df = pd.DataFrame(data=np.random.randint(1,100,(4)), index=index, columns=["P"])
P
A 5 5
6 51
B 5 93
6 76
Теперь предположим, что мы хотим выбрать строки с P> 90 . Как бы Вы это сделали? df[df["P"] > 90]
, правильно? Но посмотрите, что на самом деле возвращает df ["P"]> 90.
A 5 True
6 True
B 5 True
6 False
Name: P, dtype: bool
Как видите, он возвращает логический ряд, соответствующий исходному индексу. Почему? Поскольку Pandas необходимо отобразить, какие значения индекса имеют эквивалентное истинное значение, он может выбрать правильный результат. Таким образом, в основном, во время операций над слайсом вы всегда будете нести этот индекс, потому что это элемент отображения для объекта.
Однако надежда не ушла. В зависимости от вашего приложения, если вы считаете, что оно на самом деле занимает огромную часть вашей памяти, вы можете потратить немного времени на выполнение следующих действий:
def df_sliced_index(df):
new_index = []
rows = []
for ind, row in df.iterrows():
new_index.append(ind)
rows.append(row)
return pd.DataFrame(data=rows, index=pd.MultiIndex.from_tuples(new_index))
df_sliced_index(df[df['P'] > 90]).index
Что дает то, что я считаю, это желаемый результат:
MultiIndex(levels=[[u'B'], [5]], labels=[[0], [0]])
Но если данные слишком велики, чтобы беспокоить вас о размере индекса, мне интересно, сколько это может стоить вам с точки зрения времени.
Автор: Ricardo Silveira Размещён: 15.09.2015 12:481 плюс
Вы можете сделать MultiIndex уникальным путем
df_slice.index = pd.MultiIndex.from_tuples(df_slice.index.unique(), names=idx.names)
который дает индекс
MultiIndex(levels=[[u'A', u'B'], [5]],
labels=[[0, 1], [0, 0]])
Автор: desiato
Размещён: 15.09.2015 11:49
0 плюса
Мой предпочтительный способ сделать это
old_idx = df_slice.index
new_idx = pd.MultiIndex.from_tuples(old_idx.to_series(), names=old_idx.names)
Автор: piRSquared
Размещён: 02.09.2016 06:59
Вопросы из категории :
- python Обработка XML в Python
- python Как я могу использовать Python itertools.groupby ()?
- python Python: На какой ОС я работаю?
- python Как я могу создать непосредственно исполняемое кроссплатформенное приложение с графическим интерфейсом на Python?
- python Вызов функции модуля с использованием его имени (строки)
- python Звук Питона («Колокол»)
- python Regex и unicode
- python Создать зашифрованный ZIP-файл в Python
- python Создайте базовый итератор Python
- python Функция транспонирования / распаковки (обратная сторона zip)?
- pandas Как загрузить файл TSV в Pandas DataFrame?
- pandas Панды конвертируют dataframe в массив кортежей
- pandas pandas - получить последнее значение определенного столбца, проиндексированного другим столбцом (получить максимальное значение определенного столбца, проиндексированного другим столбцом)
- pandas Как изменить dtype определенных столбцов numpy recarray?
- pandas Контрольные диаграммы в Python
- pandas Как вы создаете указатель даты и времени в пандах
- pandas python-pandas and databases like mysql
- pandas Панды: простое «соединение» не работает?
- pandas Pandas DataFrame - Найти строку, в которой значения для столбца максимальны
- pandas Преобразование вывода Pandas GroupBy из Series в DataFrame