【问题标题】:Converting a pandas multi-index series to a dataframe by using second index as columns通过使用第二个索引作为列将 pandas 多索引系列转换为数据框
【发布时间】:2017-10-23 20:47:02
【问题描述】:

您好,我有一个具有 2 级多索引和一列的 DataFrame/Series。我想取二级索引并将其用作列。例如(代码取自multi-index docs):

import pandas as pd
import numpy as np

arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
          ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
s = pd.DataFrame(np.random.randn(8), index=index, columns=["col"])

看起来像:

first  second
bar    one      -0.982656
       two      -0.078237
baz    one      -0.345640
       two      -0.160661
foo    one      -0.605568
       two      -0.140384
qux    one       1.434702
       two      -1.065408
dtype: float64

我想要的是有一个索引为[bar, baz, foo, qux] 和列[one, two] 的DataFrame。

【问题讨论】:

    标签: python pandas numpy scipy


    【解决方案1】:

    你只需要unstack你的系列:

    >>> s.unstack(level=1)
    second       one       two
    first                     
    bar    -0.713374  0.556993
    baz     0.523611  0.328348
    foo     0.338351 -0.571854
    qux     0.036694 -0.161852
    

    【讨论】:

    • 在此之后我也做了“s.columns = s.columns.droplevel(0)”
    【解决方案2】:

    这是使用数组重塑的解决方案 -

    >>> idx = s.index.levels
    >>> c = len(idx[1])
    >>> pd.DataFrame(s.values.reshape(-1,c),index=idx[0].values, columns=idx[1].values)
              one       two
    bar  2.225401  1.624866
    baz  1.067359  0.349440
    foo -0.468149 -0.352303
    qux  1.215427  0.429146
    

    如果您不关心出现在索引顶部的名称 -

    >>> pd.DataFrame(s.values.reshape(-1,c), index=idx[0], columns=idx[1])
    second       one       two
    first                     
    bar     2.225401  1.624866
    baz     1.067359  0.349440
    foo    -0.468149 -0.352303
    qux     1.215427  0.429146
    

    给定数据集大小的时间 -

    # @AChampion's solution
    In [201]: %timeit s.unstack(level=1)
    1000 loops, best of 3: 444 µs per loop
    
    # Using array reshaping step-1
    In [199]: %timeit s.index.levels
    1000000 loops, best of 3: 214 ns per loop
    
    # Using array reshaping step-2    
    In [202]: %timeit pd.DataFrame(s.values.reshape(-1,2), index=idx[0], columns=idx[1])
    10000 loops, best of 3: 47.3 µs per loop
    

    【讨论】:

    • 这是我一直考虑的选项。如果不是所有索引都存在于所有级别,那就很冒险了。换句话说,多索引不代表笛卡尔积。
    【解决方案3】:

    另一个强大的解决方案是使用.reset_index.pivot

    levels= [['bar', 'baz'], ['one', 'two', 'three']]
    index = pd.MultiIndex.from_product(levels, names=['first', 'second'])
    series = pd.Series(np.random.randn(6), index)
    
    df = series.reset_index()
    # Shorthand notation instead of explicitly naming index, columns and values
    df = df.pivot(*df.columns)
    

    结果:

    second       one     three       two
    first                               
    bar     1.047692  1.209063  0.891820
    baz     0.083602 -0.303528 -1.385458
    

    【讨论】:

      猜你喜欢
      • 2021-08-28
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      • 2019-04-14
      • 2016-09-26
      • 1970-01-01
      • 2019-05-04
      • 2020-07-11
      相关资源
      最近更新 更多