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_amax
、points_prev_amin
、gf_prev_amax
、gf_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_series
和 str.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 中设置敏感度标签?