码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-11-14 17:53:06      阅读:75      评论:0      收藏:0      [点我收藏+]

标签:记录   time   数据   row   有关   object   多列   str   ict   

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

1、在array中储存tuple

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

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

你得到的结果会是:

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

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

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

现在你得到的结果是:

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

 

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

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

# 最小前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]]

结果:

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)

 

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

你有没有过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)

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

 

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

标签:记录   time   数据   row   有关   object   多列   str   ict   

原文地址:https://www.cnblogs.com/silence-gtx/p/11858869.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!