N多Notebook技巧让你的Jupyter notebook起飞

作为一个数据科学工作者,小白也好,大神也好,Jupyter notebook或者jupyter lab
是必备的工具。相比VS, pycharm等IDE(集成开发环境), notebook足够简单,可以让你把所有的精力放在数据探索和算法开发上面。因为其代码结构是以单元格来组织和分割。一个单元格可以有一行或者若干行代码,完成一个单元格后可以立马运行查看中间结果并以及可视化。
这种代码组织和运行方式非常符合我们的思维习惯。我们可以一边做,然后考然后根据运行的中间结果在思考下一步的操作。因为我们的大脑容量有限,很难去计算很多程序的中间结果。而在IDE里面,每次要想知道中间结果需要打断点调试或者用print函数打印出来,每次都需要从头运行,没有notebook方便。

在日常工作中,我经常是用notebook做一些数据探索或者思路演示。等确认这么做能够实现业务需求后才转向Pycharm进行工程化开发打包等。很多时候向别人讲解你的开发思路时,使用notebook配合markdown笔记,可以做出媲美教科书的效果。因为其易用和可扩展,现在很多大学都用来作上课的课件工具。另外你写完的notebook也可以发给别人(.ipynb文件),在Anaconda中可以直接运行。

下面我就总结一下日常使用notebook中的一些奇技淫巧。这些技巧掌握了,可以直接让你的notebook起飞,让你从小白变大神,从此菜鸟是路人!体验飞起来的畅快感!

  1. 单元格内执行shell命令
    很多时候别人开发的脚本是以.py文件形式保存的,这样的脚本一般需要在终端或者IDE环境中执行。其实用notebook也完全没问题。只要把终端执行的命令前加个" ! "号即可。
    例如下面我们写一个小脚本输出当前的工作环境目录以及该目录下的所有文件:
# 以下为demo.py脚本文件的内容
import os
print("this is a demo")
print('------' * 10)
print('当前的目录为:')
print(os.getcwd())
print('------' * 10)
print('当前目录下的文件:')
print(os.listdir())
print('------' * 10)

把该文件保存在当前notebook的环境下,直接在单元格中输入‘!python demo.py’即可运行脚本,和终端一样。这样我们就不用来回切换了,方便!结果如下:

image.png

既然在加个‘!’就可以执行shell命令,很多大聪明是不是就想到了可以直接在单元格内执行"!pwd", "!ls" 等Linux里面的命令呢?答案是可以的,但是windows环境中不行,但是windows环境中,把"!"改成魔法命令“%”即可执行,如下:

# "!pwd", "!ls"等可以在Linux环境中执行,改成%即可在windows环境中执行
%pwd #输出当前环境目录, 等同于os.getcwd()
>>>'C:\\Users\\11_25\\10_sucai'
%ls # #输出当前环境目录下所有目录和文件
>>> Volume in drive C has no label.
 Volume Serial Number is 8E14-AF13

 Directory of C:\Users\11_25\10_sucai

2021/11/26  17:41              .
2021/11/26  17:41              ..
2021/11/26  17:25              .ipynb_checkpoints
2021/11/23  09:14             7,746 demo.csv
2021/11/23  09:55               203 demo.py
2021/11/26  17:41            27,711 Notebook使用技巧.ipynb
               3 File(s)         35,660 bytes
               3 Dir(s)  69,066,891,264 bytes free
  1. 一个单元格多输出
    Notebook一个好用的特点就是一个单元格内的代码执行后立马输出中间结果。但是有个缺点就是默认情况下只有单元格内最后一行的代码结果会输出。例如我们使用pandas读取一个文件生成dataframe后,想了解这个df的size, columns, 前5行等信息,正常情况下df.head, df.shape, df.info等内容要分成三个单元格来完成。但其实有更好的方法,可以让一个单元格内输出多个内容。具体方法是增加一个单元格执行下面两行代码即可:
    from IPython.core.interactiveshell import InteractiveShell
    InteractiveShell.ast_node_interactivity = "all"

效果如下:


image.png
  1. 查看当前notebook中的所有变量和变量值
    在MATLAB中,直接有一个窗口可以显示当前所有的变量及其相应的值,这个功能非常强大。Anaconda中Spyder也有类似的功能。其实notebook也可以,直接使用%who和%whos魔法命令即可。其中:
  • %who会输出当前notebook中已经存在的变量
  • %whos除了输出变量外,变量的类型以及当前值也会显示

效果如下:


image.png
  1. 运行时间统计,这个比较常用。主要有time,和timeit两个魔法,命令,在结合行模式和单元格模式就有4种用法,具体如下:
  • %time:在行模式下,统计代码运行一次所花费的时间
  • %%time:在单元模式下,统计整个单元格内的代码运行一次所花费的时间
  • %timeit:在行模式下,执行代码块若干次,统计出平均时间。结果以mean+/-std的形式给出
  • %%timeit:在单元模式下,执行代码块若干次,统计出平均时间。结果以mean+/-std的形式给出
    所以time只统计执行一次的时间;而timeit会反复执行很多次统计平均时间,这个比只执行一次要准确一点。举例如下:
    首先看行模式,即代码只有一行,放在%time或者%timeit之后:我们用一个列表解析式来输出100以内可以被7整除的数:
image.png

在看看单元格模式,使用带两个%%的魔法命令。我们分别使用for循环和矩阵模式来实现矩阵的相加,看看基于numpy的矩阵运算是不是比for循环更高效:

# 1. 先定义两个二维列表
import numpy as np
m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
n = [[2, 2, 2], [3, 3, 3], [4, 4, 4]]
m_, n_ = np.array(m), np.array(n)
m_,n_
m_.shape
>>>(array([[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]]),
 array([[2, 2, 2],
        [3, 3, 3],
        [4, 4, 4]]))
(3, 3)

# 2. 分别使用for循环和numpy完成矩阵相加
# for循环版本
def v1():
    res = np.zeros((3,3))
    for row in range(m_.shape[0]):
        for col in range(m_.shape[1]):
            res[row,col] = int(m_[row,col] + n_[row,col])
    return res

# 矩阵版本
def v2():
    return m_+ n_

# 查看两个版本的结果是否相同
v1()
v2()

>>>
array([[ 3.,  4.,  5.],
       [ 7.,  8.,  9.],
       [11., 12., 13.]])
array([[ 3,  4,  5],
       [ 7,  8,  9],
       [11, 12, 13]])

在进行时间统计:


image.png

可以看到v2的矩阵运算用时和for循环不在一个数量级上,要快10倍以上!

  1. 进度条功能
    这个在之前的文章里提过, 参考 5分钟搞定几百张表格转换,Python办公自动化就是这么6! - (jianshu.com)
    主要就是使用tqdm这个工具给循环语句增加个进度插件,显示循环体进行到那个阶段了。这个功能在处理耗时比较大的循环的时候是非常必要的!效果如下:
    image.png

    具体使用方法可以参考上面的文章

好了,本次就介绍这么多,希望对你有所帮助!

你可能感兴趣的:(N多Notebook技巧让你的Jupyter notebook起飞)