Pandas:有没有办法使用“droplevel”之类的东西,并且在处理过程中,使用删除的级别标签作为前缀/后缀重命名另一个级别?

Posted

技术标签:

【中文标题】Pandas:有没有办法使用“droplevel”之类的东西,并且在处理过程中,使用删除的级别标签作为前缀/后缀重命名另一个级别?【英文标题】:Pandas: Is there a way to use something like 'droplevel' and in process, rename the other level using the dropped level labels as prefix/suffix? 【发布时间】:2017-01-17 06:34:20 【问题描述】:

以下查询的屏幕截图:

有没有一种方法可以轻松删除上层列索引,并拥有一个带有 points_prev_amaxpoints_prev_amingf_prev_amaxgf_prev_amin 等标签的单层?

【问题讨论】:

【参考方案1】:

使用list comprehension 设置新的列名:

df.columns = df.columns.map('_'.join)

Or:

df.columns = ['_'.join(col) for col in df.columns]

示例:

df = pd.DataFrame('A':[1,2,2,1],
                   'B':[4,5,6,4],
                   'C':[7,8,9,1],
                   'D':[1,3,5,9])

print (df)
   A  B  C  D
0  1  4  7  1
1  2  5  8  3
2  2  6  9  5
3  1  4  1  9

df = df.groupby('A').agg([max, min])

df.columns = df.columns.map('_'.join)
print (df)
   B_max  B_min  C_max  C_min  D_max  D_min
A                                          
1      4      4      7      1      9      1
2      6      5      9      8      5      3

print (['_'.join(col) for col in df.columns])
['B_max', 'B_min', 'C_max', 'C_min', 'D_max', 'D_min']

df.columns = ['_'.join(col) for col in df.columns]
print (df)
   B_max  B_min  C_max  C_min  D_max  D_min
A                                          
1      4      4      7      1      9      1
2      6      5      9      8      5      3

如果需要prefix简单的元组交换项:

df.columns = ['_'.join((col[1], col[0])) for col in df.columns]
print (df)
   max_B  min_B  max_C  min_C  max_D  min_D
A                                          
1      4      4      7      1      9      1
2      6      5      9      8      5      3

另一种解决方案:

df.columns = ['_'.format(i[1], i[0]) for i in df.columns]
print (df)
   max_B  min_B  max_C  min_C  max_D  min_D
A                                          
1      4      4      7      1      9      1
2      6      5      9      8      5      3

如果 len 的列很大 (10^6),那么宁可使用 to_seriesstr.join

df.columns = df.columns.to_series().str.join('_')

【讨论】:

【参考方案2】:

使用@jezrael 的设置

df = pd.DataFrame('A':[1,2,2,1],
                   'B':[4,5,6,4],
                   'C':[7,8,9,1],
                   'D':[1,3,5,9])

df = df.groupby('A').agg([max, min])

分配新列
from itertools import starmap

def flat(midx, sep=''):
    fstr = sep.join([''] * midx.nlevels)
    return pd.Index(starmap(fstr.format, midx))

df.columns = flat(df.columns, '_')

df

【讨论】:

@jezrael 这是我今天想出的一个新的 ;-) 理解还是稍微快一点。 我认为有一个例外 - 如果列的 len 非常大(很少 10^6),那么这会更快。 df.columns = df.columns.to_series().str.join('_')。但我认为实际上columns 的 len 很小,所以列表理解更好。 @jezrael 当有更多关卡时它也会更快。 pd.MultiIndex.from_product([list('ABCD'), range(4), list('wxyz')]) 顺便说一句,我很惊讶然后没有这个功能。 @jezrael 我也是。我们中的一个人应该开始为熊猫做贡献:-)

以上是关于Pandas:有没有办法使用“droplevel”之类的东西,并且在处理过程中,使用删除的级别标签作为前缀/后缀重命名另一个级别?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法使用 Python Pandas 读取所有行直到遇到空行

Python:有没有办法直接使用 Pandas 系列对象而不使用列表

有没有办法使用 Pandas Dataframes 在 Excel 中设置敏感度标签?

Pandas:有没有办法遍历数据框并使用多个条件创建新的数据框?

有没有办法使用 python pandas 进行分组?

有没有办法将Pandas整合到画面中?