Python技术迷

公司裁员时,老板认为技术总监薪资过高便将其辞退。不料总监一走,整个研发部门迅速陷入瘫痪,各项项目全面停摆。

刚看到个贴子,说一家公司裁员时,老板觉得技术总监工资太高,直接让人走人。结果呢,总监一走,研发部门全线瘫痪,项目停摆,老板急得团团转,最后不得不花两倍薪水把人请回来。

Image

很多老板看待员工,只盯着“成本”,却忽略了“价值”。技术总监拿高薪不是白来的,他背后是整个系统的逻辑、流程、甚至人心的稳定。就像拆房子时你以为只是拔颗钉,结果整个屋顶塌了。

网友有说老板活该,也有人说总监该走。我倒觉得,这其实反映了一个职场真相:真正有价值的人,不怕被裁,只怕被误解。公司省下的薪水,最终都要花更大的代价去补。

舍得给价值买单,才能少走弯路。【备注:文末可领最新资料】

面试题:创建新列

昨天晚上十一点多,我在公司楼下吹风,手机上小李发来个表格,说“哥,能不能给我新建几列,那个…按条件算的那种”。我叼着奶茶吸管想了两秒,嗯,这事儿别整花活儿,用 Python 里 pandas,干脆利落,对吧。

先把话放这儿,最常见的就是“直接算一个”。比如单价×数量,别 for 循环,直接矢量化,快得很:

import pandas as pd

df = pd.DataFrame({
"price":[19.9, 29.9, 9.9],
"qty":[3, 1, 10]
})
df["amount"] = df["price"] * df["qty"]     # 新列:总价

有人问我“要分级啊,比如金额分段标签”,我说别手搓 if-else,那太啰嗦,用 pd.cut 就行,哦对是 cut:

df["bucket"] = pd.cut(
    df["amount"],
    bins=[0, 50, 100, float("inf")],
    labels=["小单","中单","大单"]
)

等会儿我先接个电话……好,继续。如果是按条件挑挑拣拣,np.where 很顺手;要多个条件,就链在一起或者先造布尔列:

import numpy as np
mask_vip = df["amount"] >= 100
df["is_vip_order"] = np.where(mask_vip, 1, 0)

还有那种“字典映射”,比如渠道代码 1/2/3 映成中文,map 一把过:

channel_map = {1:"淘宝", 2:"京东", 3:"自营"}
df["channel_name"] = df["channel_code"].map(channel_map).fillna("未知")

要是同一用户里想算“每笔金额占这个用户总金额的占比”,这时候别 groupby 后 merge,直接 transform,优雅:

df["user_total"] = df.groupby("user_id")["amount"].transform("sum")
df["ratio_in_user"] = df["amount"] / df["user_total"]

顺嘴提一句,时间列也常用,比如下单时间映射工作日/周末,dt 属性很好用:

df["order_time"] = pd.to_datetime(df["order_time"])
df["is_weekend"] = df["order_time"].dt.weekday >= 5

有人总喜欢链式赋值,结果冒出来个 SettingWithCopyWarning,看着心烦。这个别犟,老老实实 loc:

# 错误味道:df[df["qty"]>5]["flag"] = 1  # 容易警告
df.loc[df["qty"]>5, "flag"] = 1# 对,稳

还有一个技巧,我平时喜欢“临时加一列再继续链式处理”,assign 用起来顺手,读起来也清楚点:

df2 = (
    df.assign(discount=lambda x: np.where(x["amount"]>100, 0.9, 1.0))
      .assign(payable=lambda x: (x["amount"] * x["discount"]).round(2))
)

对了分类型也别忘了,像 “小单/中单/大单” 这种固定集合,转 category 既省内存又快点点:

df["bucket"] = df["bucket"].astype("category")

性能上就两句话:一是能矢量化就矢量化,尽量让一整列去算,别在 Python 层写 for;二是尽量少 apply 到行上,行级 apply 大多慢,而且可读性一般。真的非要自定义逻辑,先考虑 np.select、where、cut、map、replace 这些“砖”,九成够用。

哦有人问导出前要不要把临时列删掉?随手 drop 就好了:

df = df.drop(columns=["user_total"])

行,我差不多说完了。等会儿我要去楼下取个外卖,那个辣子鸡别放香菜…算了先发你们这几个片段,照着抄改就能过线,出了问题再@我。

-END-

我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

🔥虎哥私藏精品🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领