Python Pandas:将Dataframe列转换为尺寸类别与计数的高效实现方法咨询
高效实现Pandas宽表转长表并映射尺寸类编号
嘿,作为Python和Pandas新手,你完全不用靠循环+if语句来搞定这个需求!Pandas内置的melt函数加上map就能轻松高效地完成,比手动循环快太多,尤其是数据量大的时候。下面一步步给你讲清楚怎么做:
第一步:准备映射关系和示例数据
首先我们先定义好尺寸类别到编号的映射字典,这样后面直接用就行:
size_mapping = { '6-12_in': 1, '12-24_in': 2, '24-54_in': 3, 'GreaterThan_54_in': 4 }
再把你的示例数据转换成DataFrame方便演示:
import pandas as pd data = { 'Plot': [1], 'Location': ['VMU'], 'Year': [2015], 'Species': ['BC'], '6-12_in': [3], '12-24_in': [None], '24-54_in': [8], 'GreaterThan_54_in': [None] } df = pd.DataFrame(data)
第二步:用melt把宽表转成基础长表
melt就是专门用来把宽表转长表的工具,我们指定哪些列是“固定不变的标识列”(id_vars),哪些列是需要拆分成行的“数值列”(value_vars):
df_long = pd.melt( df, id_vars=['Plot', 'Location', 'Year', 'Species'], # 这些列保持每行的对应关系不变 value_vars=list(size_mapping.keys()), # 要拆分的尺寸类列 var_name='Size_Original', # 存储原来的尺寸类列名 value_name='Count' # 存储对应的数量值 )
这一步之后,你会得到一个包含所有尺寸类的长表,但里面会有一些空的Count值(比如示例里的12-24_in没有数据)。
第三步:过滤无效行并映射编号
先把没有数量的行删掉,避免干扰:
df_long = df_long.dropna(subset=['Count']).reset_index(drop=True)
然后用map函数把原来的尺寸类列名转换成对应的编号,这一步是矢量化操作,比循环快N倍:
df_long['Size_Class'] = df_long['Size_Original'].map(size_mapping)
第四步:整理最终结果
最后调整一下列的顺序,删掉临时的Size_Original列,就得到你想要的格式了:
final_df = df_long[['Plot', 'Location', 'Year', 'Species', 'Size_Class', 'Count']] print(final_df)
输出结果和你想要的完全一致:
Plot Location Year Species Size_Class Count 0 1 VMU 2015 BC 1 3.0 1 1 VMU 2015 BC 3 8.0
为什么这个方法更好?
- 效率高:
melt和map都是Pandas底层优化过的矢量化操作,比Python层面的循环快得多,数据量越大优势越明显 - 代码简洁:几行代码就搞定,可读性强,维护起来也方便
- 扩展性好:如果以后新增尺寸类,只需要修改
size_mapping字典就行,不用改循环逻辑
内容的提问来源于stack exchange,提问作者xanabobana
相关产品推荐
相关产品推荐

