工作表重排序

需求:

一季度发货明细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)

 

posted @ 2021-05-04 16:41  正在学Python  阅读(221)  评论(0编辑  收藏  举报