zoukankan      html  css  js  c++  java
  • 深夜Python

    深夜Python - 第1夜 - for 迷 in 迷思

      在一个月黑风高的夜晚,我悄悄打开编辑器,进入程序的世界。刚刚学会Python的我,由于一段时间的过度装B,被委托优化一段程序,我信心十足地接下来,看了又看……这不挺好的程序吗?但是又觉得哪不太对,无奈,只好去找夜猫兄。

      “夜猫兄!速救!——”我敲门敲出了过年放烟花般的氛围。夜猫兄刚刚起床,瞅瞅我的程序,然后瞅瞅我,一脸鄙夷:“这……是你写的?”

      “这是……其实是β兄的原创……”我感觉不妙……

      “真差!”夜猫兄只说了这2个字。

      “啥啥啥?”我满脸问号。上贡了十袋小鱼干,三杯热牛奶,终于让夜猫兄满意,同意传授我Python秘籍。夜猫兄亲自上手,带着我把代码优化了一遍。

      优化的位置很多,一段一段来看。

    1 testdata = np.zeros((1, 80, 30))  ###   1  80  36
    2 for i in range(80):  ##   80
    3     for j in range(30):
    4         testdata[0, i, j] = m[i, j]

      这可以看成一段C语言里初始化数组的程序,其中np为numpy库,m为80×30的数组,testdata用于数据分类,必须增加一个维度,所以有了上面的程序,它类似于如下C语言代码:

    1 int testdata[1][80][30] = {0};
    2 int i,j;
    3 for(i=0; i<80; i++){
    4     for(j=0; j<30; j++){
    5         testdata[0][i][j] = m[i][j];
    6     }
    7 }

      “夜猫兄,这不就是C语言的改写吗?有什么问题吗?”

      “Python的优势就是它语法很简洁,开发起来很高效,所以用Python模仿C开发就很搞笑。看我给你重写这段代码。”

      还没等我反应过来,夜猫兄的爪子就敲完了键盘……我一看,啥啥啥?这就行了?

    1 testdata = m.reshape((1, 80, 30))

      “reshape是numpy自带的方法,可以重新组织数据,通俗点说,改变数组的形状。numpy底层是C语言实现的,所以速度比用Python的for快得多,而且代码简洁易读,这么写都不用加注释了。”

      “对对对,夜猫兄威武!”

      “多说一句,注意reshape函数是有别的参数可以用的,就是order。默认order='C',就是上面的效果,order='F'就会按照列的顺序排列数据,还有个'A',具体的去看官方文档。给你演示一下。”

     1 >>> a = np.arange(12)
     2 >>> a.reshape((4,3))
     3 array([[ 0,  1,  2],
     4        [ 3,  4,  5],
     5        [ 6,  7,  8],
     6        [ 9, 10, 11]])
     7 >>> a.reshape((4,3), order='C')
     8 array([[ 0,  1,  2],
     9        [ 3,  4,  5],
    10        [ 6,  7,  8],
    11        [ 9, 10, 11]])
    12 >>> a.reshape((4,3), order='F')
    13 array([[ 0,  4,  8],
    14        [ 1,  5,  9],
    15        [ 2,  6, 10],
    16        [ 3,  7, 11]])

      "哇,学到了学到了。"我笑嘻嘻地搓着手,“诶,那下面那段……”

      “对,类似的。”夜猫兄捻起一条小鱼干,嘬了一口牛奶,改起了下面的代码:

    1 tdata = np.zeros((47, 4))
    2 ...
    3 data = tctimeClient.recv(47 * 4 * 4)  # 40ms  4字节
    4 ptr = 0
    5 for i in range(47 * 4):
    6     tdata[ptr % 47][ptr // 47] = struct.unpack('f', data[4 * i:4 * i + 4])[0]  # / 浮点数除,//整除
    7     ptr += 1

      这段代码中data是接收到的字节数据,数据类型需要转换成float32,所以需要用struct修改数据类型,类似于C语言的强制类型转换。当然聪明如我——夜猫兄的高手在C语言里会用union(共用体)来实现类型的转换。会用C语言的童鞋可以看出,tdata[ptr % 47][ptr // 47]就是按照列的顺序排列数据。但是如夜猫兄所说,这样的做法在Python里非常低效的,应该用现成的库代替。而struct.unpack是可以多字节操作的,所以应该用47×4个'f'一次性把数据全转换掉。

    1 byte_data = tctimeClient.recv(47 * 4 * 4)  # 40ms  4字节
    2 float_data = struct.unpack('f'*47*4, byte_data)
    3 tdata = np.array(float_data).reshape((47, 4), order='F')

      “夜猫兄,给讲讲struct呗~”

      “自己搜去!”夜猫兄只顾着改代码,不太愿意理我,我只好再掏出来一罐小鱼干……“这是官方文档,下次自己搜啊。”

      ……

      光阴似箭……牛奶杯渐渐见底……夜猫兄的爪子停了下来,“今天就到这吧,我要睡午觉了,代码慢慢改吧。”

      “哈?你是不是就是想要小鱼干和牛奶?”

      “闭嘴,你走!”夜猫兄一口干了剩下的小鱼干,把罐子扔给我,“垃圾什么的都带走啊!”

       深夜Python,第1夜,2019.10.16。

  • 相关阅读:
    Windows XP下 Android开发环境 搭建
    Android程序的入口点
    在eclipse里 新建android项目时 提示找不到proguard.cfg
    64位WIN7系统 下 搭建Android开发环境
    在eclipse里 新建android项目时 提示找不到proguard.cfg
    This Android SDK requires Android Developer Toolkit version 20.0.0 or above
    This Android SDK requires Android Developer Toolkit version 20.0.0 or above
    Android requires compiler compliance level 5.0 or 6.0. Found '1.4' instead
    Windows XP下 Android开发环境 搭建
    Android程序的入口点
  • 原文地址:https://www.cnblogs.com/adjwang/p/11681646.html
Copyright © 2011-2022 走看看