如何用一个Pandas DataFrame的值作为另一个的列名且无需循环?
无需循环!用Pandas批量映射DataFrame标签值
当然可以!完全不用写繁琐的逐日期/列循环,用Pandas的向量式操作就能高效搞定这个映射需求,而且代码简洁易懂。
先帮你把示例数据整理成可直接运行的代码,方便测试:
import pandas as pd # 创建示例df1 df1 = pd.DataFrame({ 'Date': ['2003-01-31', '2003-02-28', '2003-03-31'], 0: ['CA', 'CA', 'CA'], 1: ['KY', 'KY', 'KY'], 2: ['ID', 'HI', 'CO'], 3: ['CO', 'CO', 'HI'] }) # 创建示例df2 df2 = pd.DataFrame({ 'Date': ['2003-01-31', '2003-02-28', '2003-03-31'], 'CA': [5, 2, 6], 'KY': [3, 7, 3], 'ID': [4, 8, 9], 'CO': [5, 4, 3], 'HI': [1, 5, 5] })
方法1:简洁直观的行匹配法
适合中小规模数据,代码一眼就能看懂:
# 将Date设为索引,方便按日期匹配df2的对应行 result = df1.set_index('Date').apply( lambda row: df2.set_index('Date').loc[row.name][row], axis=1 ).reset_index() # 恢复原df1的列名格式 result.columns = ['Date', 0, 1, 2, 3]
原理说明
df1.set_index('Date')把日期设为索引,让每一行的row.name就是当前日期df2.set_index('Date').loc[row.name]直接取出df2中对应日期的所有州数值- 最后用当前行的州代码列表(
row)作为索引,一次性取出所有对应数值,这一步是向量式操作,不是逐元素循环
方法2:纯向量式的长格式转换法
适合大规模数据,全程无隐性循环,效率拉满:
# 把df1转成长格式:拆分出「日期、列序号、州代码」 df1_long = df1.melt(id_vars='Date', var_name='col', value_name='state') # 把df2转成长格式:拆分出「日期、州代码、对应数值」 df2_long = df2.melt(id_vars='Date', var_name='state', value_name='value') # 按「日期+州代码」合并,匹配对应数值 merged = df1_long.merge(df2_long, on=['Date', 'state']) # 转回宽格式,恢复原df1的结构 result = merged.pivot(index='Date', columns='col', values='value').reset_index() # 调整列名和顺序,和原df1一致 result.columns = ['Date', 0, 1, 2, 3]
原理说明
通过melt把两个宽表转成结构一致的长表,用merge完成批量匹配,最后用pivot转回宽表,全程都是Pandas的内置向量操作,完全规避了循环,处理大数据时性能优势明显。
最终输出结果
运行上述任意一种方法,都会得到你需要的DataFrame:
Date 0 1 2 3 0 2003-01-31 5 3 4 5 1 2003-02-28 2 7 5 4 2 2003-03-31 6 3 3 5
内容的提问来源于stack exchange,提问作者grumpycylon
相关产品推荐
相关产品推荐

