python - 移动 Pandas 多索引值,使它们在非空白下方没有空白

标签 python pandas multi-index

考虑以下 dfpd.MultiIndex

col = pd.MultiIndex.from_tuples([('stat1', '', ''), ('stat2', '', ''),
                                 ('A', 'mean', 'blue'), ('A', 'mean', 'red'),
                                 ('B', 'var', 'blue'), ('B', 'var', 'red')])

df = pd.DataFrame(np.arange(24).reshape(4, 6), list('abcd'), col)

df

enter image description here

我不希望 stat1stat2 位于顶部。我希望它们像这样位于底部:

enter image description here


一个夸张的例子更能说明问题

col = pd.MultiIndex.from_tuples([('a', '', ''), ('', 'b', ''),
                                 ('c', 'd', ''), ('e', '', 'f'),
                                 ('g', 'h', 'i'), ('', 'j', 'k')])

df = pd.DataFrame(np.arange(24).reshape(4, 6), list('abcd'), col)

df

enter image description here

应该看起来像:

enter image description here


我试过:

c = np.array(col.values.tolist())

c_ = pd.MultiIndex.from_tuples(np.sort(c).tolist())

pd.DataFrame(df.values, df.index, c_)

enter image description here

这是不正确的,因为某些列以我不希望的方式排序。


时机

到目前为止,@root 获得了计时奖。我认为我不太关心更大的指数。这主要是为了报告。

代码

def pir(df):
    base = df.columns.to_series().apply(pd.Series).reset_index(drop=True)
    rplc = pd.DataFrame(np.where(base == '', None, base))
    data = {k:v.dropna()[::-1].reset_index(drop=True) for k, v in rplc.iterrows()}
    new_col = pd.MultiIndex.from_tuples(pd.DataFrame(data)[::-1].fillna('').T.values.tolist())

    return pd.DataFrame(df.values, df.index, new_col)

def kartik(df):
    new_cols = []
    for col in df.columns:
        col = list(col)
        if col[2] == '':
            col[2] = col[0]
            col[0] = ''
        new_cols.append(col)

    return pd.DataFrame(df.values, df.index, list(map(list, zip(*new_cols))))

def so44(df):
    tuple_list = df.columns.values
    new_tuple_list = []

    for t in tuple_list:
        if t[2] == '':
            if t[1] == '':
                t = (t[1], t[2], t[0])
            else:
                t = (t[2], t[0], t[1])
        elif t[1] == '' and t[0] != '':
            t = (t[1], t[0], t[2])

        new_tuple_list.append(t)

    return pd.DataFrame(df.values, df.index, pd.MultiIndex.from_tuples(new_tuple_list))

def root(df):
    new_cols = [['']*col.count('')+[x for x in col if x] for col in df.columns.values]
    return pd.DataFrame(df.values, df.index, pd.MultiIndex.from_tuples(new_cols))


    return pd.DataFrame(df.values, df.index, pd.MultiIndex.from_tuples(new_tuple_list))

enter image description here

最佳答案

重新排列每个列元组的通用方法:

new_cols = [['']*col.count('')+[x for x in col if x != ''] for col in df.columns.values]
df.columns = pd.MultiIndex.from_tuples(new_cols)

它可能不如针对特定级别数调整的其他方法那么快,但它很简洁并且应该适用于任意数量的级别。

关于python - 移动 Pandas 多索引值,使它们在非空白下方没有空白,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38882595/

相关文章:

python - 在多列上过滤 Pandas 数据框的最快方法

python - 我正在尝试 Stack、Melt、Grouby 或 reshape Pandas DataFrame

python - 如何加载预训练的 PyTorch 模型?

Python 正则表达式 : parsing newick format

python - 匹配子字符串的替代解决方案

python - 如何在一次热编码后聚合行

c++ - 多索引插入失败返回( boost )

python - 如何根据列名通过方法重新采样 Pandas 多索引数据帧

python - 多个相同的标签名称和 lxml.objectify

python - 使用脚本将文件从 UNIX 复制到 Windows