将 Excel 多列转多行, 两层循环, 下标取值, 类似指针在 二维数组的移动, 核心就是循环, 和索引

也是最近的一个需求, 将一个 Excel 表, 多列转多行, 就把那种行的, 业务人员经常搞的那种垃圾表,给它转为咱熟悉的数据库表的形式, 多列转多行. 还要帮他们处理数据, 恶心得一批, 其实也不一定非要用什么 Pandas , 就循环遍历二维数据而已, 可能是, Pandas 比较很好, 就总是会将它作为我的第一选择, 事实证明, 它确实无敌强, 理论上能处理任何数据的骚操作.

需求

注: 写错字了, 木有 “两”, 就是 前 4 列, 尴尬得一批.

方案

  • 读取数据为一个数据, 用 Pandas 来读, iloc 来索引值, 根据下标
  • 两个 for 循环, 分别代表两个方向 (垂直 和 水平) 谁先谁后, 无所谓的, 结果不变, 只是顺序变了.
  • 假设我们, 外层循环为水平方向, 内层则为 垂直方向. (外层每移动 1 列, 内层则移动 n 行)
  • 最后把所有的结果, 拼接起来, 存为 Excel 即可

实现

这里我用我小伙伴的代码吧, 自己就不写了, 写啥代码, 要什么自行车.. 会搬砖, 收藏, 还有模仿, 这才是代码成功之道

核心代码

df = pd.read_excel(file_path)

columns = df.columns.values

# 需要转置的那部分 DF
row_n = df.shape[0] -1
col_n = df.shape[1] - 4

ret = []  # 大列表来存储所有的

# 外层水平向右1列, 内层垂直向下遍历移多行
for i in range(col_n):
    for j in range(row_n):
        # 索引取值 iloc[行索引,列索引] 即可
        lst = [
            
            # 先取前四列, j+1 是为了跳过第 2 行
            df.iloc[j+1, 0], df.iloc[j+1, 1],
            df.iloc[j+1, 2], df.iloc[j+1, 3],
            
            # 再取当前列的, 前两行, 和 对应的值 (i,j) 再来3个字段
            
            columns[i+4], # 当前的列名, columns 是列字段列表
            df.iloc[0, i+4],  # 第一行,当前列的那个值, 即字段下面那个
            df.iloc[j+1, i+4] # j 是不断往下走, 边走边取值
        ]
        
        # 每一次取值, 则作为新数据的一行
        ret.append(lst)
        
# 最后再将这个新的二维数据变为 DataFrame, cols 自定义, 存 Excel 即可
      

之列来一波运行效果呀

完整代码

import pandas as pd 

def get_data(file_path):
    """将Excel读取为DF"""
    return pd.read_excel(file_path)


def col_to_row(df):
    """多行转多列,返回转好的二维数组"""
    columns = df.columns.values
    # 需要转置的那部分 DF
    row_n = df.shape[0] -1
    col_n = df.shape[1] - 4

    ret = [] 
    for i in range(col_n):
        for j in range(row_n):
            # 索引取值 iloc[行索引,列索引] 即可
            lst = [
                # 先取前四列, j+1 是为了跳过第 2 行
                df.iloc[j+1, 0], df.iloc[j+1, 1],
                df.iloc[j+1, 2], df.iloc[j+1, 3],
                # 再取当前列的, 前两行, 和 对应的值 (i,j) 再来3个字段
                columns[i+4], 
                df.iloc[0, i+4], 
                df.iloc[j+1, i+4]
            ]
             # 每一次取值, 则作为新数据的一行
            ret.append(lst)
    
    return ret



def save_excel(d2_array, col_names, save_path):
    """将一个二维数组,拼接为DF 再存为Excel"""
    pd.DataFrame(d2_array, 
      columns=col_names).to_excel(
        save_path, index=False
    )
    
    
# 主逻辑
data = get_data("D:/test_data/多列转多行.xlsx")  # 获取数据
d2_array = col_to_row(data)  # 处理数据

col_names = [\'name\',\'gender\',\'age\',	\'major\', \'I\', \'AM\', \'NB\']
save_excel(d2_array, col_names, "D:/youge.xlsx")  # 存储数据

print("ok!")

然后来看一波, 结果, 从 Excel.

小结

  • 行列转换, 除了用什么 stack(), pivot, melt 之类的, 也有看需求, 暴力来循环的
  • 这个案例关键在于, 两个 for 循环来移动取值(下标) , 类似于, 指针移动在二维数组中
  • 理解原理就行, 多搬砖和收藏点赞才是偷懒的唯一途径

版权声明:本文为chenjieyouge原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/chenjieyouge/p/12846780.html