Pandas:取消组合并融化空格缩进的记录
Posted
技术标签:
【中文标题】Pandas:取消组合并融化空格缩进的记录【英文标题】:Pandas: ungroup and melt space-indented records 【发布时间】:2020-01-27 12:40:56 【问题描述】:我是 python&pandas 的新手,能否请您告知我是否可以取消分组和取消透视此类数据框?
源数据中的组位于唯一用前缀空格标记的列中,看起来像
import pandas as pd
import numpy
df = pd.DataFrame([
['Costs', numpy.nan, numpy.nan, numpy.nan],
[' Vehicles', numpy.nan, numpy.nan, numpy.nan],
[' Cars', numpy.nan, numpy.nan, numpy.nan],
[' BMW', 1000, 1100, 1010],
[' Toyota', 1203, 1302, 1322],
[' Cars - Total', 2203, 2402, 2332],
[' Trucks', numpy.nan, numpy.nan, numpy.nan],
[' Volvo', 5000, 5001, 5010],
[' MAN', 5500, 5055, 5066],
[' Trucks - Total', 10500, 10056, 10076],
[' Vehicles - Total', 12703, 12458, 12408],
[' Crew', numpy.nan, numpy.nan, numpy.nan],
[' Gomez Addams', 10000, 10000, 10000],
[' Morticia Addams', 10000, 10000, 10000],
[' Crew - Total', 20000, 20000, 20000],
['Costs - Total', 32703, 32458, 32408],
],
columns=['Level', 'Q1_2019', 'Q2_2019', 'Q3_2019'])
我需要将其转换为类似的表格
Level, Sublevel1, Sublevel2, Sublevel3, Sublevel4, Date, Value
"Costs", "Vehicles", "Cars", "BMW", "Q1_2019", 1000
"Costs", "Crew", "Gomez Addams", , "Q1_2019", 10000
现在我已经创建了额外的“子级”列,用正则表达式回填它们,然后逐行填充子级间隙,然后应用 melt()。可以做得更pythonish吗?
【问题讨论】:
您可以执行 print(df) 或 df.to_dict()。这将使其他人更容易做出贡献。 ***.com/questions/20109391/… 由于空间量在您的问题中很重要,我建议您提供一个由pd.DataFrame
构建的示例数据框,以便人们尝试复制和粘贴您拥有的数据集时不会出错现在。
pd.read_csv(StringIO(d),sep='|',skiprows=1).iloc[:,1:-1].dropna(how='all')
使用 StringIO 正确读取带有空格的数据帧。 d
是保存在多行字符串中的表格
不适合我@Datanovice,但最好的做法还是以人们可以轻松重现您的问题的方式包含您的数据集。例如pd.DataFrame
或df.to_dict
@Erfan 您是否也将表格复制到您的编辑器中?我先这样做了,它在一个多行字符串"""table"""
中刚刚在一个新的虚拟环境上再次测试,它工作正常
【参考方案1】:
这可能是一种更简洁的方法,但想法是使用Total
过滤掉组,然后使用后向和前向填充。
然后,我们将出现次数少于 1 次的任何东西放入组中,并按 1-2 级融化
df['sub_level'] = df['Level'].str.count('\s+')
df.loc[df["Level"].str.contains("Total"), "group"] = (
df["Level"].str.strip().str.replace("- Total", "")
)
df['group'] = df['group'].bfill().ffill()
df = df[df.groupby('group')['group'].transform('count') > 1].dropna(how='any')
final_df = pd.melt(
df.loc[df["sub_level"].isin([1, 2])].drop("sub_level", axis=1), id_vars=["Level",'group']
)
final_df.columns = ['Level','Type','Date','Value']
print(final_df)
Level Type Date Value
0 BMW Cars Q1_2019 1000.0
1 Toyota Cars Q1_2019 1203.0
2 Volvo Trucks Q1_2019 5000.0
3 MAN Trucks Q1_2019 5500.0
4 Gomez Addams Crew Q1_2019 10000.0
5 Morticia Addams Crew Q1_2019 10000.0
6 BMW Cars Q2_2019 1100.0
7 Toyota Cars Q2_2019 1302.0
8 Volvo Trucks Q2_2019 5001.0
9 MAN Trucks Q2_2019 5055.0
10 Gomez Addams Crew Q2_2019 10000.0
11 Morticia Addams Crew Q2_2019 10000.0
12 BMW Cars Q3_2019 1010.0
13 Toyota Cars Q3_2019 1322.0
14 Volvo Trucks Q3_2019 5010.0
15 MAN Trucks Q3_2019 5066.0
16 Gomez Addams Crew Q3_2019 10000.0
17 Morticia Addams Crew Q3_2019 10000.0
【讨论】:
以上是关于Pandas:取消组合并融化空格缩进的记录的主要内容,如果未能解决你的问题,请参考以下文章