野路子码农系列(7)近期花里胡哨技巧汇总

近期并无什么系统性的学习感悟,反而是在项目过程当中练就了一些奇技淫巧。最近作的工做大部分都跟优化执行效率有关,把原来要泡茶等的代码优化到快如闪电,有时候仍是很是有意思的,顺便跟大神们聊天也受益良多,记录一下最近用到的一些之后可能还会反复用的技巧吧:python

一、在array中储存tupleapp

你试过在array中储存tuple吗?这个问题有些蛋疼,但特殊需求没办法。我一开始觉得这个问题很简单,但没想到tuple进去全变list了……致使我后来找某个特定的tuple时提示找不到。有人可能会说list和tuple差很少啊,但tuple是hashable的,这也是咱们坚持要tuple的缘由。dom

idx = [("a", 1), ("a", 2), ("b", 5)]
np.array(idx)

你获得的结果会是:函数

array([['a', '1'],
       ['a', '2'],
       ['b', '5']], dtype='<U1')

惊不惊喜?意不意外?后来总算找到了一种方法,必须先新建一个空的array,并制定dtype,以后再赋值:oop

arr = np.empty((len(idx)), dtype="object")
arr[:] = idx
arr

如今你获得的结果是:学习

array([('a', 1), ('a', 2), ('b', 5)], dtype=object)

 

二、数值最大(或最小)的前n项所对应的对象优化

有点绕口,举个例子说,我有学生ABCDE,我还有一次考试的成绩,我想知道班级前三是谁。我原来想的是用OrderedDict,后来大神教了我正宗numpy方法,速度固然没的说:spa

# 最小前3项(带排序)
student = np.array(["A", "B", "C", "D", "E", "F", "G"])
score = np.array([92, 84, 93, 85, 83, 88, 91])
nth = 3

student[np.argpartition(score, nth-1)[:nth]]

结果:code

array(['E', 'B', 'D'], dtype='<U1')

若是要最大,加个负号就好了:对象

# 最大前4项(带排序)
student = np.array(["A", "B", "C", "D", "E", "F", "G"])
score = np.array([92, 84, 93, 85, 83, 88, 91])
nth = 4

student[np.argpartition(-score, nth-1)[:nth]]

结果:

array(['C', 'A', 'G', 'F'], dtype='<U1')

 

三、函数矢量化(向量化)

你有没有过apply的痛苦经验?当数据量不断增大以后,你会发现稍微复杂的一个apply会变得很是慢,尤为是涉及多列的apply。这时候要如何才能摆脱龟速呢?我当时第一想法是numba?然而numba不用@njit至关于白用,但@njit不支持不少python原生的类型(好比dict),更别谈支持DataFrame了。这时候你须要的是np.vectorize:

首先咱们随便弄一些数据,先来个5W行吧

df = pd.DataFrame({"a":np.random.random(50000), "b":np.random.random(50000)})

而后咱们的函数是个基于a、b两列的条件判断:

def func(a, b):
    if (a < 0.5) & (b < 0.5):
        return 1
    elif (a >=0.5) & (b < 0.5):
        return 2
    else:
        return 3

按照传统的apply方法咱们运行一下:

%%timeit
df["c"] = df.apply(lambda row: func(row["a"], row["b"]), axis=1)

结果:

1.11 s ± 32.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

好了,如今上魔法,只需短短一行:

v_func = np.vectorize(func)

再来计时一下看看:

%%timeit
df["c"] = v_func(df["a"], df["b"])

结果:

13.4 ms ± 294 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

快如闪电!现已加入特征工程套餐。