【问题标题】:How to select ONLY THE INDEX COLUMNS in a pandas multi-index Dataframe?如何在熊猫多索引数据框中仅选择索引列?
【发布时间】:2018-05-28 04:36:13
【问题描述】:

好的,所以我有一个带有 2 列索引的 DataFrame,我正在尝试过滤该 DataFrame 中的行,并仅将原始数据帧的索引列保留到新的过滤 DataFrame 中。

我通过以下方式从 CSV 文件创建了数据框:查找 CSV 文件 here

census_df = pd.read_csv("census.csv", index_col = ["STNAME", "CTYNAME"])
census_df.sort_index(ascending = True)

然后,我对 DataFrame 应用了一些过滤,效果非常好,我得到了所需的行。我使用的代码如下所示:

def my_answer():

    mask1 = census_df["REGION"].between(1, 2)
    mask2 = census_df.index.get_level_values("CTYNAME").str.startswith("Washington")
    mask3 = (census_df["POPESTIMATE2015"] > census_df["POPESTIMATE2014"])
    new_df = census_df[mask1 & mask2 & mask3]
    return pd.DataFrame(new_df.iloc[:, -1])

my_answer()

问题来了:

上面的代码返回一个数据框,其中包含索引和第一列以及 2 个索引列。我想要的只是两个索引列。 因此,最终答案应该返回一个 DATAFRAME,其中包含“STNAME”和“CTYNAME”,其中包含 5 行。

【问题讨论】:

  • 你想用return pd.DataFrame(new_df.iloc[:, 0])代替return new_df.reset_index()吗?
  • @jezrael 不,不起作用。它返回所有我不想要的列。我只想要列“STNAME”和“CTYNAME”。另外,我不只是希望它们作为列。我希望它们作为索引,也是一种排序方式。

标签: python-3.x pandas dataframe multi-index


【解决方案1】:

您可以将index 转换为DataFrame

def my_answer():

    mask1 = census_df["REGION"].between(1, 2)
    mask2 = census_df.index.get_level_values("CTYNAME").str.startswith("Washington")
    mask3 = (census_df["POPESTIMATE2015"] > census_df["POPESTIMATE2014"])
    new_df = census_df[mask1 & mask2 & mask3]
    return pd.DataFrame(new_df.index.tolist(), columns=['STNAME','CTYNAME'])

print (my_answer())

         STNAME            CTYNAME
0          Iowa  Washington County
1     Minnesota  Washington County
2  Pennsylvania  Washington County
3  Rhode Island  Washington County
4     Wisconsin  Washington County

如果想要输出为MultiIndex 需要MultiIndex.remove_unused_levels,但它在pandas 0.20.0+ 中工作:

def my_answer():

    mask1 = census_df["REGION"].between(1, 2)
    mask2 = census_df.index.get_level_values("CTYNAME").str.startswith("Washington")
    mask3 = (census_df["POPESTIMATE2015"] > census_df["POPESTIMATE2014"])
    new_df = census_df[mask1 & mask2 & mask3]
    return new_df.index.remove_unused_levels()

print (my_answer())

MultiIndex(levels=[['Iowa', 'Minnesota', 'Pennsylvania', 'Rhode Island', 'Wisconsin'], 
                   ['Washington County']],
           labels=[[0, 1, 2, 3, 4], [0, 0, 0, 0, 0]],
           names=['STNAME', 'CTYNAME'])

【讨论】:

  • AttributeError: 'MultiIndex' 对象没有属性 'to_frame'
  • 您的建议是重置索引,我认为这对我不起作用。尽管框架的视图如我所愿,但输出并不理想。我想要两个实体——“STNAME”和“CTYNAME”——作为索引,而不是列。
  • @ArchanJoshi - 在 pandas 中,return pd.DataFrame(new_df.index.tolist(), columns=['STNAME','CTYNAME']).to_string(index=False) 可以实现,但它将数据帧转换为字符串。
  • 但默认情况下,如果需要,则无法删除索引DataFrame object
  • 有没有办法返回视图或以某种方式引用数据框的索引列,同时将它们保留为索引?
【解决方案2】:

使用列表推导:

def my_answer():
     mask1 = census_df["REGION"].between(1, 2)
     mask2 = census_df.index.get_level_values("CTYNAME").str.startswith("Washington")
     mask3 = (census_df["POPESTIMATE2015"] > census_df["POPESTIMATE2014"])
     new_df = census_df[mask1 & mask2 & mask3]

     return pd.DataFrame([new_df.index[x] for x in range(len(new_df))])    

my_answer()

输出:

    0              1
 0  Iowa         Washington County
 1  Minnesota    Washington County
 2  Pennsylvania Washington County
 3  Rhode Island Washington County
 4  Wisconsin    Washington County``

【讨论】:

    猜你喜欢
    • 2018-06-19
    • 2020-01-12
    • 2014-10-01
    • 2017-10-30
    • 2017-03-12
    • 2015-02-22
    • 1970-01-01
    • 1970-01-01
    • 2016-06-13
    相关资源
    最近更新 更多