当前位置: 首页 > 面试题库 >

数据框切片不会删除索引值

景宏富
2023-03-14
问题内容

我最近在大型数据框及其关联的多索引中遇到了此问题。这个简化的示例将演示该问题。

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

即使使用.copy(deep = 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]])

当数据帧很大时,实际上就会出现问题。


问题答案:

我了解您的关注,但我相信您必须了解熊猫低级应用程序中正在发生的事情。

首先,我们必须声明索引应该是不可变的。您可以在此处查看其更多文档-> http://pandas.pydata.org/pandas-
docs/stable/indexing.html#setting-metadata

当创建一个数据框对象时,让我们命名它,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

如您所见,它返回一个与原始索引匹配的布尔系列。为什么?因为熊猫需要映射哪些索引值具有相等的真实值,所以它可以选择适当的结果。因此,基本上,在切片操作期间,您将始终携带此索引,因为它是对象的映射元素。

但是,希望没有消失。根据您的应用程序,如果您认为它实际上占用了很大一部分内存,则可以花一些时间来执行以下操作:

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

但是,如果数据太大而不必担心索引的大小,那么我想知道它会花费多少时间。



 类似资料:
  • 问题内容: 用更多索引范围(例如by和)对数据帧进行切片的pythonic方法是什么? 我想要一个更优雅的方式: 结果: 像这样的东西会更优雅: 问题答案: 您可以使用numpy的“切片技巧”: 给出:

  • 如前所述,对象中的元素遵循基于零的索引。 有三种可用的索引方法类型: 字段访问,基本切片和高级索引。 基本切片是 Python 中基本切片概念到 n 维的扩展。 通过将start,stop和step参数提供给内置的slice函数来构造一个 Python slice对象。 此slice对象被传递给数组来提取数组的一部分。 输出如下: [2 4 6] 在上面的例子中,ndarray对象由arang

  • 问题内容: 我有一个数据框。 我想选择在所有指数是 不是 在列表中, 现在,我使用列表理解来创建所需的标签以进行切片。 工作正常,但如果我经常需要这样做可能会很笨拙。 有一个更好的方法吗? 问题答案: 在索引上使用并反转布尔索引以执行标签选择:

  • 问题内容: 在文档(http://dev.mysql.com/doc/refman/6.0/en/drop- table.html )中未明确提及。我问是因为我刚刚在Rails项目中看到了一个奇怪的数据库迁移,其中开发人员在删除表之前删除了所有索引,这似乎是不必要的。 问题答案: 是的,它确实。 但是,如果您具有诸如RESTRICT之类的外键约束来确保与其他表的参照完整性,则需要在删除或截断表之前

  • 主要内容:基本切片,多维数组切片在 NumPy 中,如果想要访问,或修改数组中的元素,您可以采用索引或切片的方式,比如使用从 0 开始的索引依次访问数组中的元素,这与 Python 的 list 列表是相同的。 NumPy 提供了多种类型的索引方式,常用方式有两种:基本切片与高级索引。本节重点讲解基本切片。 基本切片 NumPy 内置函数 slice() 可以用来构造切片对象,该函数需要传递三个参数值分别是 start(起始索引

  • 我有一个dataframe,。 我想选择中不在列表中的所有索引,