妹子发给我一张公司要处理的绩效表格,我以为很简单,然而菜是原罪 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
smartG
V2EX    问与答

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

  •  a href="Javascript:" Onclick="downVoteTopic(632268);" class="vote">
  •   smartG 2019-12-25 18:00:33 +08:00 4744 次点击
    这是一个创建于 2129 天前的主题,其中的信息可能已经有所发展或是发生改变。

    妹子发给我一个她们公司 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()) 
    第 1 条附言    2019-12-26 09:36:40 +08:00

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

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

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

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

    首先,定义分数对应等级,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
    zmxnv123
        11
    zmxnv123  
       2019-12-25 19:30:37 +08:00
    想知道妹子去哪领
    zeroDev
        12
    zeroDev  
       2019-12-25 19:32:43 +08:00 via Adroid
    可以试试 openpyxl 库处理
    wangkun025
        13
    wangkun025  
       2019-12-25 19:33:48 +08:00
    继续用 excel,不要考虑 Python
    JCZ2MkKb5S8ZX9pq
        14
    JCZ2MkKb5S8ZX9pq  
       2019-12-25 19:35:10 +08:00
    直接 excel 插几个过程列好了,搞完还给她个简化版。
    xlcoder166
        15
    xlcoder166  
       2019-12-25 19:38:03 +08:00
    是关于员工等级评定的,有 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  
       2019-12-25 19:40:16 +08:00 via iPhone
    excel 多加几个辅助列
    passluo
        17
    passluo  
       2019-12-25 19:48:12 +08:00
    卧槽这个也太简单了吧……

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

    电子表格这种系统的设计就是鼓励大家去计算一些中间统计结果,再计算出最终结果,为啥一定要一个函数解决所有问题啊。
    xlcoder166
        18
    xlcoder166  
       2019-12-25 19:57:12 +08:00
    题外话 我很好奇 在这种条件下能拿 A 的都是啥神仙啊 =.=
    smartG
        19
    smartG  
    OP
       2019-12-25 19:59:01 +08:00 via iPhone
    @passluo 多谢!看了大家的评论才发现我把问题复杂化了,我对 Excel 的函数功能了解不多,只知道 Python 可以处理批量数据,低估了 Excel 本身的强大功能
    smartG
        20
    smartG  
    OP
       2019-12-25 20:03:29 +08:00 via iPhone
    @xlcoder166 是每项单独的,百分制,不是最多降两级,有几项不及格就降几级,我看了一下,很少有超过两项不及格的
    DEANHZED
        21
    DEANHZED  
       2019-12-25 20:05:40 +08:00 via iPhone
    妹子国二没过吧?
    smartG
        22
    smartG  
    OP
       2019-12-25 20:05:54 +08:00 via iPhone
    @zeroDev 好的,我试一下!
    smartG
        23
    smartG  
    OP
       2019-12-25 20:06:15 +08:00 via iPhone
    @wangkun025 是的,用 Python 反而更复杂了
    smartG
        24
    smartG  
    OP
       2019-12-25 20:06:41 +08:00 via iPhone
    @zmxnv123 哈哈哈就是人事妹子
    smartG
        25
    smartG  
    OP
       2019-12-25 20:07:03 +08:00 via iPhone
    @zhy0216 i 好像有点问题……
    smartG
        26
    smartG  
    OP
       2019-12-25 20:07:53 +08:00 via iPhone
    @pzhzp 好的,明天上班试试,多谢啦
    smartG
        27
    smartG  
    OP
       2019-12-25 20:11:44 +08:00 via iPhone
    @DEANHZED 妹子用的 if,and 函数,多层嵌套……
    c6h6benzene
        28
    c6h6benzene  
       2019-12-25 20:14:08 +08:00 via iPhone
    我觉得 Excel 单独就能解决(但没有表格我也不知道在说什么
    lithiumii
        29
    lithiumii  
       2019-12-25 20:40:32 +08:00 via Android
    等级是不是不够?低于 60 也算 D ?还是算不及格?
    smartG
        30
    smartG  
    OP
       2019-12-25 21:08:55 +08:00 via iPhone
    @lithiumii 是啊,没写全,后面还有的
    labubu
        31
    labubu  
       2019-12-25 21:16:27 +08:00
    Excel 导出 csv 然后 python 操作 csv 简单一点
    jedicxl
        32
    jedicxl  
       2019-12-25 21:33:09 +08:00
    @xlcoder166 大型国企都这路数啊,我们公司就这么搞
    snw
        33
    snw  
       2019-12-25 22:15:00 +08:00 via Android
    这不就是多加几列算中间过程的事吗……
    yalin
        34
    yalin  
       2019-12-25 22:18:37 +08:00
    我也是用 pandas 各种弄
    sx90
        35
    sx90  
       2019-12-25 22:48:16 +08:00 via Android
    vba 了解一下
    lithiumii
        36
    lithiumii  
       2019-12-25 22:49:56 +08:00   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  
       2019-12-25 23:07:36 +08:00   1
    https://docs.qq.com/sheet/DR1J1Q1ltSGJ3ZWF1?c=F2A0A0 闲着贴一个 excel 出来;当然,可以将所有中间步骤函数合并到一起
    xiongdong57
        38
    xiongdong57  
       2019-12-25 23:08:14 +08:00   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  
       2019-12-25 23:09:29 +08:00   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  
       2019-12-26 09:07:33 +08:00
    我有个朋友 excel 贼溜,想问一下在哪领妹子?
    smartG
        41
    smartG  
    OP
       2019-12-26 09:22:11 +08:00
    @Telegram 感谢大佬!我尝试一下用 VBA,越发感觉出来 Excel 的强大了
    @xiongdong57 好的,我试一下,感谢!
    @AlphaTr 按着您的做出来啦,感谢感谢!
    @lithiumii 是的,逻辑差不多,就是代码写不出来,向大佬学习啦,感谢!
    lework1234
        42
    lework1234  
       2019-12-26 13:17:50 +08:00
    office 套件没用好啊。
    kn007
        43
    kn007  
       2019-12-26 19:56:27 +08:00
    过来 mark 一下
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     992 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 18:33 PVG 02:33 LAX 11:33 JFK 14:33
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86