有个需求需要处理Excel表格,将宽表的形式变成窄表,也就是行转列,如果是二位表格,直接利用pandas.melt()
函数进行处理就可以。
但是如果表格比较复杂,可能会有合并单元格,有相同列名的情况,需要通过一些其他的处理来完成,自己写了个代码可以应对这些情况:
import pandas as pd
from pathlib import Path
# 解决控制台输出显示补全
pd.set_option('display.max_rows', 50000)
pd.set_option('display.max_columns', 10000)
pd.set_option('display.width', 100000)
# 创建空表,输出路径
writer = pd.ExcelWriter('输出路径')
# 读取excel
# skip:指定跳过的行数; skiprows:跳过前面几行,包括表头; dtype:防止padans将整数数据读为浮点数
data=pd.read_excel('输入路径', header=2, dtype=str)
#data=data.fillna(method="ffill") #列合并单元格补全
data=data.iloc[:,1:] #读取指定行指定列
# 替换由于合并单元格产生的空值表头
data.rename(columns={'Unnamed: 1':'xxx'}, inplace=True) #解决行合并单元格产生的Unnamed问题
# 宽表展窄表
#参数说明: id_vars:保持不变的列索引
# var_name:行索引转列索引后新的列名
# value_name:value_name:新索引对应的值的列名
data=data.melt(id_vars='content_tag_value',var_name='user_tag_value',value_name='weight')
# 根据一列生成新的一列
# 需要利用pandas读取相同列名时自动添加的.1区分相同的列,后面再除去.1
data[' '] = data[' '].apply(lambda x: 'x' if x=='x1'or x=='x2' or x=='x3'
else 'y' if x == 'y1' or x == 'y2'
else 'z')
# 替换pandas自动为相同列添加的.1
data=data.replace({'xxx.1':'xxx','yyy.1':'yyy', , , })
data=data.replace({'xxx.2':'xxx','yyy.2':'yyy', , , })
# 交换列的顺序
order = ['col1', 'col2', 'col3', , ]
data = data[order]
# 保存到excel
data.to_excel(writer, index=None)
# 关闭,会调用.save()方法将数据保存
writer.close()
#diff = data1.compare(data2, align_axis=0)
# 打印值
print("转换后的值:\n{0}\n".format(data))
基本上可以满足复杂表格的行转列情况,对于函数要查阅资料,灵活应用。