V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
smartG
V2EX  ›  问与答

妹子发给我一张公司要处理的绩效表格,我以为很简单,然而菜是原罪

  •  
  •   smartG · Dec 25, 2019 · 5067 views
    This topic created in 2319 days ago, the information mentioned may be changed or developed.

    妹子发给我一个她们公司 100 多人的 Excel 表格,是关于员工等级评定的,有 N1,N2,N3,N4(百分制得分 /按权重 10%,20%,50%,20%计算)四项得分和总分 sum

    标准如下:

    • 如果 sum 在 90 分以上,为等级 A,80-90:等级 B,70-80:等级 C,60-70:等级 D
    • 如果在上述四项中有一项低于 60 分,等级顺降一级,两项低于 60 分,降两级

    尝试的方法:

    • 妹子自己用的 Excel 表格自带的函数,无果,目前正在手动计算等级
    • 我以前了解过 python 的一些库,知道 pandas 可以处理表格,倒腾了一会儿没有搞出来,python 语法也是现学,这段代码运行后只能显示了第二行的结果 B
    • 大佬们有什么好的处理这个表格的方法吗?,Excel 函数或者其他方法都行,手动计算其实也用不了多少时间,但是应该有更高效的方法,求教!

    代码部分( python 小白,大佬轻喷)

    import pandas as pd  
    data1=pd.read_excel("C:/Users/acer/Desktop/绩效.xlsx")  
    def final (num1):  
        if (num1==10):  
            return "A"  
        elif(num1==9):  
            return "B"  
        elif(num1==8):  
            return "C"  
        elif(num1==7):  
            return "D"  
        elif (num1==6):  
            return "E"
    
    def c_f1():  
        for i in range(5):  
            def c_f(first_number):  
                num=0  
                if(data1.iloc[i].values[1]<6):  
                    num+=1  
                elif(data1.iloc[i].values[2]<12):  
                    num+=1  
                elif(data1.iloc[i].values[3]<30):  
                    num+=1  
                elif(data1.iloc[i].values[4]<12):  
                    num+=1  
                return first_number-num  
    
            if (data1.iloc[i].values[5]>=90):
                    n1=c_f(10)
                    return final(n1)
            elif(data1.iloc[i].values[5]>=80 and data1.iloc[1].values[5]<90):
                    n1=c_f(9)
                    return final(n1)
            elif(data1.iloc[i].values[5]>=70 and data1.iloc[1].values[5]<80):
                    n1=c_f(8)
                    return final(n1)
            elif(data1.iloc[i].values[5]>=60 and data1.iloc[1].values[5]<70):
                    n1=c_f(7)
                    return final(n1)
            elif(data1.iloc[i].values[5]>=50 and data1.iloc[1].values[5]<60):
                    n1=c_f(6)
                    return final(n1)
    print(c_f1())
    
    Supplement 1  ·  Dec 26, 2019

    感谢各位大佬,给妹子发过去了,借鉴的AlphaTr老哥贴出的在线文档:

    https://docs.qq.com/sheet/DR1J1Q1ltSGJ3ZWF1?c=F2A0A0

    我也会把各位说的方法都尝试一遍,毕竟妹子们经常用表格,嘿嘿,你们懂的

    43 replies    2019-12-26 19:56:27 +08:00
    pzhzp
        1
    pzhzp  
       Dec 25, 2019 via iPhone
    excel 貌似 sum()-countif()*2 算一个最终总分再分级就可以实现?
    pzhzp
        2
    pzhzp  
       Dec 25, 2019 via iPhone
    @pzhzp 错了*10
    singerll
        3
    singerll  
       Dec 25, 2019 via Android
    sum-n1/60 取整-n2/60 取整-。。。。
    turan12
        4
    turan12  
       Dec 25, 2019 via iPhone
    设置一个过渡字段
    wmhx
        5
    wmhx  
       Dec 25, 2019
    用 sql 来统计 不容易么?
    happydezhangning
        6
    happydezhangning  
       Dec 25, 2019
    工具人?
    syahd
        7
    syahd  
       Dec 25, 2019 via iPhone   ❤️ 1
    楼主应该把脱敏后的表格发出来方便大神操作,推荐腾讯表格分享
    zhy0216
        8
    zhy0216  
       Dec 25, 2019
    你把 c_f 函数的 i 打印出来看看
    kokutou
        9
    kokutou  
       Dec 25, 2019 via Android
    中间过渡下。。。
    先算 sum 等级,再算低于 60 等级。
    查的时候也好查呀。
    sunmker
        10
    sunmker  
       Dec 25, 2019
    我有一个想法:

    首先,定义分数对应等级,A:10,B:9,C:8,D:7

    其次,通过 excel 的筛选功能分别筛选出“按照 sum 划分”的 ABCD,专门使用一列(比如 G )填上 ABCD 所对应的分数 10、9、8、7 (这个筛选出来后直接可以利用 excel 批量操作,下同)

    然后,在开辟四列(比如 H、I、J、K )分别用函数 =IF(A1<6,1,0) 这个判断公式来标记是否不及格,不及格记录 1,及格 0

    接着,就是阅读理解了,「如果在上述四项中有一项低于 60 分,等级顺降一级,两项低于 60 分,降两级」,这个是最多降两级( A ),还是最多 4 级( B )

    如果是情况B,直接L列=G-H-I-J-K,然后你接着用筛选功能。一次筛选L列值为10的,在M列填上A,然后依次批量填完所有的……
    如果是情况A,那你可以用L求和HIJK列,筛选,<2 的在M列=G-L,>= 2 的M列=G-2。然后筛选M列为10填写A……9填写B
    xe2vherd
        11
    xe2vherd  
       Dec 25, 2019
    想知道妹子去哪领
    zeroDev
        12
    zeroDev  
       Dec 25, 2019 via Android
    可以试试 openpyxl 库处理
    wangkun025
        13
    wangkun025  
       Dec 25, 2019
    继续用 excel,不要考虑 Python
    JCZ2MkKb5S8ZX9pq
        14
    JCZ2MkKb5S8ZX9pq  
       Dec 25, 2019
    直接 excel 插几个过程列好了,搞完还给她个简化版。
    xlcoder166
        15
    xlcoder166  
       Dec 25, 2019
    是关于员工等级评定的,有 N1,N2,N3,N4(百分制得分 /按权重 10%,20%,50%,20%计算)四项得分和总分 sum

    (N1 * 0.1) + (N2 * 0.2) + (N3 * 0.5) + (N4 * 0.2)

    如果 sum 在 90 分以上,为等级 A,80-90:等级 B,70-80:等级 C,60-70:等级 D

    a + b + c + d = result (A B C D)

    如果在上述四项中有一项低于 60 分,等级顺降一级,两项低于 60 分,降两级

    ? 这个标准有歧义啊

    1. 上诉四项低于 60 分, 这个 60 分指定那个 N1 还是 N1 * 0.1 ,
    2. 是最多降 2 级吗?


    思路

    先算总值的条件 1, 再判断条件 2 的情况
    dunn
        16
    dunn  
       Dec 25, 2019 via iPhone
    excel 多加几个辅助列
    passluo
        17
    passluo  
       Dec 25, 2019
    卧槽这个也太简单了吧……

    - sum 计算为一列 > C1
    - C1 按区间匹配出 ABCD 等,分别对应成 4321 > C2
    - countifs 统计一下每行低于 60 分单元格的数量 > C3
    - C2-C3 得出最后的分段 > C4
    - 把 C4 结果 1234 再对应回 DBCA > C5
    - 把 C1-C4 隐藏……

    电子表格这种系统的设计就是鼓励大家去计算一些中间统计结果,再计算出最终结果,为啥一定要一个函数解决所有问题啊。
    xlcoder166
        18
    xlcoder166  
       Dec 25, 2019
    题外话 我很好奇 在这种条件下能拿 A 的都是啥神仙啊 =.=
    smartG
        19
    smartG  
    OP
       Dec 25, 2019 via iPhone
    @passluo 多谢!看了大家的评论才发现我把问题复杂化了,我对 Excel 的函数功能了解不多,只知道 Python 可以处理批量数据,低估了 Excel 本身的强大功能
    smartG
        20
    smartG  
    OP
       Dec 25, 2019 via iPhone
    @xlcoder166 是每项单独的,百分制,不是最多降两级,有几项不及格就降几级,我看了一下,很少有超过两项不及格的
    DEANHZED
        21
    DEANHZED  
       Dec 25, 2019 via iPhone
    妹子国二没过吧?
    smartG
        22
    smartG  
    OP
       Dec 25, 2019 via iPhone
    @zeroDev 好的,我试一下!
    smartG
        23
    smartG  
    OP
       Dec 25, 2019 via iPhone
    @wangkun025 是的,用 Python 反而更复杂了
    smartG
        24
    smartG  
    OP
       Dec 25, 2019 via iPhone
    @zmxnv123 哈哈哈就是人事妹子
    smartG
        25
    smartG  
    OP
       Dec 25, 2019 via iPhone
    @zhy0216 i 好像有点问题……
    smartG
        26
    smartG  
    OP
       Dec 25, 2019 via iPhone
    @pzhzp 好的,明天上班试试,多谢啦
    smartG
        27
    smartG  
    OP
       Dec 25, 2019 via iPhone
    @DEANHZED 妹子用的 if,and 函数,多层嵌套……
    c6h6benzene
        28
    c6h6benzene  
       Dec 25, 2019 via iPhone
    我觉得 Excel 单独就能解决(但没有表格我也不知道在说什么
    lithiumii
        29
    lithiumii  
       Dec 25, 2019 via Android
    等级是不是不够?低于 60 也算 D ?还是算不及格?
    smartG
        30
    smartG  
    OP
       Dec 25, 2019 via iPhone
    @lithiumii 是啊,没写全,后面还有的
    labubu
        31
    labubu  
       Dec 25, 2019
    Excel 导出 csv 然后 python 操作 csv 简单一点
    jedicxl
        32
    jedicxl  
       Dec 25, 2019
    @xlcoder166 大型国企都这路数啊,我们公司就这么搞
    snw
        33
    snw  
       Dec 25, 2019 via Android
    这不就是多加几列算中间过程的事吗……
    yalin
        34
    yalin  
       Dec 25, 2019
    我也是用 pandas 各种弄
    sx90
        35
    sx90  
       Dec 25, 2019 via Android
    vba 了解一下
    lithiumii
        36
    lithiumii  
       Dec 25, 2019   ❤️ 1
    贴代码没有缩进,那干脆就一行一行来了,还能展示计算过程,其实 py 跟 excel 差不多,多加几步路就是了。

    import pandas as pd

    # 假定这个 excel 读进来就四列,n1, n2, n3, n4,每一行一个人
    df = pd.read_excel("C:/Users/acer/Desktop/绩效.xlsx")

    # 先数每个人挂了几科
    df["n_failed"] = df.apply(lambda x: sum(x < 60), axis=1)

    # 加权求和,反正权重是死的硬编码就是了
    df["sum"] = df["n1"] * 0.1 + df["n2"] * 0.2 + df["n3"] * 0.5 + df["n4"] * 0.2

    # 从 sum 得到用数字表示的等级( 5: A, 4: B, 3: C, 2: D, 小于 2 的不及格 F )
    df["raw_grade_int"] = df["sum"].apply(lambda x:int(x / 10) - 4)

    # 挂几科降几级
    df['final_grade_int'] = df["raw_grade_int"] - df['n_failed']

    # 从数字表示的等级转为 ABCDF,用个硬编码的字典对应
    df['final_grade']=df['final_grade_int'].apply(lambda x: {5: "A", 4: "B", 3: "C", 2: "D"}.get(x, 'F'))

    # 跳过不需要的列用于输出
    output_df = df[['n1', 'n2', 'n3', 'n4','final_grade']]

    # 输出,不需要 index
    output_df.to_excel("C:/Users/acer/Desktop/工具人.xlsx", index = False)
    AlphaTr
        37
    AlphaTr  
       Dec 25, 2019   ❤️ 1
    https://docs.qq.com/sheet/DR1J1Q1ltSGJ3ZWF1?c=F2A0A0 闲着贴一个 excel 出来;当然,可以将所有中间步骤函数合并到一起
    xiongdong57
        38
    xiongdong57  
       Dec 25, 2019   ❤️ 1
    def category(x):
    # column contains N1,N2,N3,N4,sum
    level = min(100 - x.loc['sum'], 30) // 10

    x = x[["N1", "N2", "N3", "N4"]]
    count = (x < 60).sum()
    category = level + min(count, 2)

    if category < 1:
    return "A"
    elif category < 2:
    return "B"
    elif category < 3:
    return "C"
    else:
    return "D"

    df['category'] = df.apply(category, axis=1)

    规则好像不全,可以全部补充到分类函数里
    Telegram
        39
    Telegram  
       Dec 25, 2019   ❤️ 1
    处理 EXCEL 当然是用自带的 VBA 最强大啊。
    https://i.loli.net/2019/12/25/524AsHLaoNiWTkY.png


    代码如下:

    Function JSS(rng As Range)
    Select Case rng(1) * 0.1 + rng(2) * 0.2 + rng(3) * 0.5 + rng(4) * 0.2

    Case 90 To 100
    sum1 = 65 'A ascii 码
    Case 80 To 89
    sum1 = 66 'B
    Case 70 To 79
    sum1 = 67 'C
    Case Is < 70
    sum1 = 68 'D
    End Select

    For i = 1 To 4
    If rng(i) < 60 Then sum2 = sum2 + 1 '统计小于 60 的个数
    If sum2 = 2 Then Exit For '两个项目小于 60,就别继续看了
    Next i

    JSS = Chr(sum1 + sum2)
    End Function


    具体使用方法:alt+F11,然后右键,插入,模块
    https://i.loli.net/2019/12/25/McivXKrDubyU59Y.png

    代码粘贴进去,然后就可以在表格里用这个函数了(函数一定要写在模块里)
    https://i.loli.net/2019/12/25/HLFiZkTRJlWVfw8.png
    x66
        40
    x66  
       Dec 26, 2019
    我有个朋友 excel 贼溜,想问一下在哪领妹子?
    smartG
        41
    smartG  
    OP
       Dec 26, 2019
    @Telegram 感谢大佬!我尝试一下用 VBA,越发感觉出来 Excel 的强大了
    @xiongdong57 好的,我试一下,感谢!
    @AlphaTr 按着您的做出来啦,感谢感谢!
    @lithiumii 是的,逻辑差不多,就是代码写不出来,向大佬学习啦,感谢!
    lework1234
        42
    lework1234  
       Dec 26, 2019
    office 套件没用好啊。
    kn007
        43
    kn007  
       Dec 26, 2019
    过来 mark 一下
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2372 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 132ms · UTC 04:23 · PVG 12:23 · LAX 21:23 · JFK 00:23
    ♥ Do have faith in what you're doing.