工作表重排序
需求:
一季度发货明细2万+行,现与客户对账,客户要求,同名收货人不能同屏出现,所有数量大于1的记录 拆成单行处理
实现:
1.将所有发货数量大于1的记录,取出来 按照数量 追加n-1行,最后将数量调整为1.完成对记录的拆分
2.按照收货人顺序排序 得到一个顺序号;同名收货人分组累计排序 得到第二个顺序号;对于出现次数超过1次的 收货人 按照出现次序*s(s=总行数/收货人重复最大数)+0.1,次数小于1的 顺序等于第一个顺序号 得到第三个顺序号
3.按照第三个顺序号排升序
4.实现过程比较容易,就是对于计算机内存需求比较大,内存不足,就算不出来了
下面是Python代码的实现过程:
import pandas as pd from pandas import DataFrame,Series import numpy as np def quantity_to_one(filename,header,sheet_name) df=pd.read_excel(filename,dtype ='str',sheet_name=sheet_name,header = header ) # 转换为整型 df['数量'] = df['数量'].astype(int) # 数量大于一的 索引行 indexs = df.loc[df['数量']>1].index # 对于数量大于1 的行,按照数量n 在df后追加n-1次。 for index in indexs[[0;500]: quantity = df.loc[index,'数量'] for i in range(1,quantity): df = df.append(df.loc[index]) # 将数量调整为1 df.loc[indexs,'数量'] = 1 filename = r'E:\***.xlsx' header = 2 sheet_name = '发货明细' quantity_to_one(filename,header,sheet_name)
import pandas as pd from pandas import DataFrame,Series import numpy as np def resort_by_receiver(filename,header,sheet_name): df=pd.read_excel(filename,dtype ='str',sheet_name=sheet_name,header=header) df.head() # 序号1 按照收货人顺序排序 df.sort_values(by=['收货人'],ignore_index=True,inplace=True) df['序号1']=df.index # 序号2 分组累计计数 df['序号2']=df.groupby('收货人')['收货人'].cumcount() # 计算乘数 num = df['收货人'].size/df.groupby('收货人')['收货人'].count().max() # xh3(xh3=序号2*num+0.1)。 df['序号3']=df['序号2']*num+0.1 df.head() # 取出收货人 不重复的行索引,让xh3的值等于对应行 序号1的值. for i in df['收货人']: indexs=df.loc[df['收货人']==i].index if indexs.size<=1: df.loc[indexs,['序号3']]=df.loc[indexs,['序号1']].values # 取出收货人为空的 行索引,让xh3的值等于对应行 序号1的值 index_nan = df.loc[df['收货人'].isnull()].index df.loc[index_nan,['序号3']]=df.loc[index_nan,['序号1']].values # 按照xh3排序,实现按照收货人的乱序。收货人相同的行 不同时出现。 df.sort_values(by='序号3',ignore_index=True,inplace=True) df.to_excel(r'e:\new.xlsx',index=False) filename = r'E:\***.xlsx' sheet_name = '发货明细' resort_by_receiver(filename,sheet_name=sheet_name,header=2)