Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 数据帧切片不删除索引值_Python_Pandas - Fatal编程技术网

Python 数据帧切片不删除索引值

Python 数据帧切片不删除索引值,python,pandas,Python,Pandas,我最近遇到了一个大型数据帧及其相关的多索引的问题。 这个简化的例子将演示这个问题 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 这将产生:

我最近遇到了一个大型数据帧及其相关的多索引的问题。 这个简化的例子将演示这个问题

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]])
MultiIndex(levels=[[u'A', u'B'], [5]],
           labels=[[0, 1], [0, 0]])
如果我切片这个数据帧,我会注意到多重索引从不压缩。 即使有一个深拷贝

在切片操作中减少索引内存占用的最佳方法是什么

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)

我希望MultiIndex删除6,如图所示:

MultiIndex(levels=[[u'A', u'B'], [5]]
    ,labels=[[0, 1], [0, 0]])

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

您可以通过

df_slice.index = pd.MultiIndex.from_tuples(df_slice.index.unique(), names=idx.names)
这就产生了指数

print df.index

MultiIndex(levels=[[u'A', u'B'], [5, 6]],
           labels=[[0, 0, 1, 1], [0, 1, 0, 1]])
MultiIndex(levels=[[u'A', u'B'], [5]],
           labels=[[0, 1], [0, 0]])

我理解您的担忧,但我相信您必须了解低级别应用程序中发生了什么

首先,我们必须声明索引应该是不可变的。您可以在此处查看更多文档->

当您创建一个dataframe对象时,让我们将其命名为
df
,并且您想要访问它的行,基本上您所做的就是传递一个布尔序列,该序列将与其对应的索引相匹配

请遵循以下示例:

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

但是,如果数据太大,您不必担心索引的大小,我想知道这可能会花费您多少时间

我更喜欢的方法是

old_idx = df_slice.index
new_idx = pd.MultiIndex.from_tuples(old_idx.to_series(), names=old_idx.names)

谢谢-那会有用的。我仍然想知道为什么它没有根本改变。里卡多-你的回答很有帮助-谢谢。我想你有一点90 v 30的拼写错误。谢谢-你给了我必要的洞察力。但是,我想我应该避免使用iterrows()并在切片操作之后执行.reset\u index(),然后紧接着执行.set\u index()。这导致多索引占用空间减少。哦,是的,这是一个打字错误。首先,我编写了大于30的代码,但随后它返回了所有值。关于重置索引,我认为您需要它,因为它们是多索引的。但好吧,我很高兴我能帮上忙。