Python 数据分析(PYDA)第三版(七)(2)https://developer.aliyun.com/article/1482402
numpy.searchsorted: 在排序数组中查找元素
searchsorted
是一个数组方法,对排序数组执行二分查找,返回值需要插入以保持排序的数组中的位置:
In [204]: arr = np.array([0, 1, 7, 12, 15]) In [205]: arr.searchsorted(9) Out[205]: 3
您还可以传递一个值数组,以获取一个索引数组:
In [206]: arr.searchsorted([0, 8, 11, 16]) Out[206]: array([0, 3, 3, 5])
您可能已经注意到searchsorted
对于0
元素返回了0
。这是因为默认行为是返回相等值组的左侧的索引:
In [207]: arr = np.array([0, 0, 0, 1, 1, 1, 1]) In [208]: arr.searchsorted([0, 1]) Out[208]: array([0, 3]) In [209]: arr.searchsorted([0, 1], side='right') Out[209]: array([3, 7])
作为searchsorted
的另一个应用,假设我们有一个值在 0 到 10,000 之间的数组,以及一个我们想要用来对数据进行分箱的单独的“桶边缘”数组:
In [210]: data = np.floor(rng.uniform(0, 10000, size=50)) In [211]: bins = np.array([0, 100, 1000, 5000, 10000]) In [212]: data Out[212]: array([ 815., 1598., 3401., 4651., 2664., 8157., 1932., 1294., 916., 5985., 8547., 6016., 9319., 7247., 8605., 9293., 5461., 9376., 4949., 2737., 4517., 6650., 3308., 9034., 2570., 3398., 2588., 3554., 50., 6286., 2823., 680., 6168., 1763., 3043., 4408., 1502., 2179., 4743., 4763., 2552., 2975., 2790., 2605., 4827., 2119., 4956., 2462., 8384., 1801.])
然后,为了确定每个数据点属于哪个区间(其中 1 表示桶[0, 100)
),我们可以简单地使用searchsorted
:
In [213]: labels = bins.searchsorted(data) In [214]: labels Out[214]: array([2, 3, 3, 3, 3, 4, 3, 3, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 4, 3, 4, 3, 3, 3, 3, 1, 4, 3, 2, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3])
这与 pandas 的groupby
结合使用,可以用于对数据进行分箱:
In [215]: pd.Series(data).groupby(labels).mean() Out[215]: 1 50.000000 2 803.666667 3 3079.741935 4 7635.200000 dtype: float64
使用 Numba 编写快速 NumPy 函数
Numba 是一个开源项目,使用 CPU、GPU 或其他硬件为类似 NumPy 的数据创建快速函数。它使用LLVM Project将 Python 代码转换为编译后的机器代码。
为了介绍 Numba,让我们考虑一个纯 Python 函数,使用for
循环计算表达式(x - y).mean()
:
import numpy as np def mean_distance(x, y): nx = len(x) result = 0.0 count = 0 for i in range(nx): result += x[i] - y[i] count += 1 return result / count
这个函数很慢:
In [209]: x = rng.standard_normal(10_000_000) In [210]: y = rng.standard_normal(10_000_000) In [211]: %timeit mean_distance(x, y) 1 loop, best of 3: 2 s per loop In [212]: %timeit (x - y).mean() 100 loops, best of 3: 14.7 ms per loop
NumPy 版本快了 100 多倍。我们可以使用numba.jit
函数将此函数转换为编译后的 Numba 函数:
In [213]: import numba as nb In [214]: numba_mean_distance = nb.jit(mean_distance)
我们也可以将其编写为装饰器:
@nb.jit def numba_mean_distance(x, y): nx = len(x) result = 0.0 count = 0 for i in range(nx): result += x[i] - y[i] count += 1 return result / count
结果函数实际上比矢量化的 NumPy 版本更快:
In [215]: %timeit numba_mean_distance(x, y) 100 loops, best of 3: 10.3 ms per loop
Numba 无法编译所有纯 Python 代码,但它支持 Python 的一个重要子集,对于编写数值算法非常有用。
Numba 是一个深度库,支持不同类型的硬件、编译模式和用户扩展。它还能够编译 NumPy Python API 的一个重要子集,而无需显式的for
循环。Numba 能够识别可以编译为机器代码的结构,同时替换对 CPython API 的调用,以便编译它不知道如何编译的函数。Numba 的jit
函数选项nopython=True
将允许的代码限制为可以在没有任何 Python C API 调用的情况下编译为 LLVM 的 Python 代码。jit(nopython=True)
有一个更短的别名,numba.njit
。
在前面的示例中,我们可以这样写:
from numba import float64, njit @njit(float64(float64[:], float64[:])) def mean_distance(x, y): return (x - y).mean()
我鼓励您通过阅读Numba 的在线文档来了解更多。下一节将展示创建自定义 NumPy ufunc 对象的示例。
使用 Numba 创建自定义 numpy.ufunc 对象
numba.vectorize
函数创建了编译后的 NumPy ufuncs,行为类似于内置的 ufuncs。让我们考虑一个numpy.add
的 Python 实现:
from numba import vectorize @vectorize def nb_add(x, y): return x + y
现在我们有:
In [13]: x = np.arange(10) In [14]: nb_add(x, x) Out[14]: array([ 0., 2., 4., 6., 8., 10., 12., 14., 16., 18.]) In [15]: nb_add.accumulate(x, 0) Out[15]: array([ 0., 1., 3., 6., 10., 15., 21., 28., 36., 45.])
高级数组输入和输出
在 Ch 4: NumPy 基础:数组和矢量化计算中,我们熟悉了np.save
和np.load
用于将数组以二进制格式存储在磁盘上。还有一些其他更复杂用途的选项需要考虑。特别是,内存映射还具有额外的好处,使您能够对不适合 RAM 的数据集执行某些操作。
内存映射文件
内存映射文件是一种与磁盘上的二进制数据交互的方法,就好像它存储在内存中的数组中一样。NumPy 实现了一个类似 ndarray 的memmap
对象,使得可以在不将整个数组读入内存的情况下读取和写入大文件的小段。此外,memmap
具有与内存中数组相同的方法,因此可以替换许多算法中预期的 ndarray 的地方。
要创建新的内存映射,请使用函数np.memmap
并传递文件路径、数据类型、形状和文件模式:
In [217]: mmap = np.memmap('mymmap', dtype='float64', mode='w+', .....: shape=(10000, 10000)) In [218]: mmap Out[218]: memmap([[0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.]])
对memmap
进行切片会返回磁盘上数据的视图:
In [219]: section = mmap[:5]
如果将数据分配给这些对象,它将被缓冲在内存中,这意味着如果您在不同的应用程序中读取文件,更改将不会立即反映在磁盘文件中。可以通过调用flush
将任何修改同步到磁盘:
In [220]: section[:] = rng.standard_normal((5, 10000)) In [221]: mmap.flush() In [222]: mmap Out[222]: memmap([[-0.9074, -1.0954, 0.0071, ..., 0.2753, -1.1641, 0.8521], [-0.0103, -0.0646, -1.0615, ..., -1.1003, 0.2505, 0.5832], [ 0.4583, 1.2992, 1.7137, ..., 0.8691, -0.7889, -0.2431], ..., [ 0. , 0. , 0. , ..., 0. , 0. , 0. ], [ 0. , 0. , 0. , ..., 0. , 0. , 0. ], [ 0. , 0. , 0. , ..., 0. , 0. , 0. ]]) In [223]: del mmap
当内存映射超出范围并被垃圾回收时,任何更改也将刷新到磁盘。打开现有内存映射时,仍然必须指定数据类型和形状,因为文件只是一个没有任何数据类型信息、形状或步幅的二进制数据块:
In [224]: mmap = np.memmap('mymmap', dtype='float64', shape=(10000, 10000)) In [225]: mmap Out[225]: memmap([[-0.9074, -1.0954, 0.0071, ..., 0.2753, -1.1641, 0.8521], [-0.0103, -0.0646, -1.0615, ..., -1.1003, 0.2505, 0.5832], [ 0.4583, 1.2992, 1.7137, ..., 0.8691, -0.7889, -0.2431], ..., [ 0. , 0. , 0. , ..., 0. , 0. , 0. ], [ 0. , 0. , 0. , ..., 0. , 0. , 0. ], [ 0. , 0. , 0. , ..., 0. , 0. , 0. ]])
内存映射也适用于结构化或嵌套数据类型,如结构化和记录数组中所述。
如果您在计算机上运行此示例,可能希望删除我们上面创建的大文件:
In [226]: %xdel mmap In [227]: !rm mymmap
HDF5 和其他数组存储选项
PyTables 和 h5py 是两个 Python 项目,提供了与 NumPy 兼容的接口,用于以高效和可压缩的 HDF5 格式(HDF 代表分层数据格式)存储数组数据。您可以安全地将数百吉字节甚至数千吉字节的数据存储在 HDF5 格式中。要了解如何在 Python 中使用 HDF5,我建议阅读pandas 在线文档。
性能提示
将数据处理代码调整为使用 NumPy 通常会使事情变得更快,因为数组操作通常会取代否则相对极慢的纯 Python 循环。以下是一些提示,可帮助您从库中获得最佳性能:
- 将 Python 循环和条件逻辑转换为数组操作和布尔数组操作。
- 尽可能使用广播。
- 使用数组视图(切片)来避免复制数据。
- 利用 ufuncs 和 ufunc 方法。
如果仅使用 NumPy 无法获得所需的性能,请考虑在 C、FORTRAN 或 Cython 中编写代码。我经常在自己的工作中使用Cython作为一种获得类似 C 性能的方法,通常开发时间更短。
连续内存的重要性
虽然这个主题的全部范围有点超出了本书的范围,在一些应用中,数组的内存布局可以显著影响计算速度。这部分基于 CPU 的缓存层次结构的性能差异;访问连续内存块的操作(例如,对 C 顺序数组的行求和)通常是最快的,因为内存子系统将适当的内存块缓冲到低延迟的 L1 或 L2 CPU 缓存中。此外,NumPy 的 C 代码库中的某些代码路径已经针对连续情况进行了优化,可以避免通用的跨步内存访问。
说一个数组的内存布局是连续的意味着元素按照它们在数组中出现的顺序存储在内存中,关于 FORTRAN(列主序)或 C(行主序)排序。默认情况下,NumPy 数组被创建为 C 连续或者简单连续。一个列主序数组,比如一个 C 连续数组的转置,因此被称为 FORTRAN 连续。这些属性可以通过flags
属性在 ndarray 上显式检查:
In [228]: arr_c = np.ones((100, 10000), order='C') In [229]: arr_f = np.ones((100, 10000), order='F') In [230]: arr_c.flags Out[230]: C_CONTIGUOUS : True F_CONTIGUOUS : False OWNDATA : True WRITEABLE : True ALIGNED : True WRITEBACKIFCOPY : False In [231]: arr_f.flags Out[231]: C_CONTIGUOUS : False F_CONTIGUOUS : True OWNDATA : True WRITEABLE : True ALIGNED : True WRITEBACKIFCOPY : False In [232]: arr_f.flags.f_contiguous Out[232]: True
在这个例子中,理论上,对这些数组的行求和对于arr_c
应该比arr_f
更快,因为行在内存中是连续的。在这里,我使用 IPython 中的%timeit
进行检查(这些结果可能在你的机器上有所不同):
In [233]: %timeit arr_c.sum(1) 199 us +- 1.18 us per loop (mean +- std. dev. of 7 runs, 1000 loops each) In [234]: %timeit arr_f.sum(1) 371 us +- 6.77 us per loop (mean +- std. dev. of 7 runs, 1000 loops each)
当你想要从 NumPy 中挤出更多性能时,这通常是一个值得投入一些努力的地方。如果你有一个数组,它没有所需的内存顺序,你可以使用copy
并传递'C'
或'F'
:
In [235]: arr_f.copy('C').flags Out[235]: C_CONTIGUOUS : True F_CONTIGUOUS : False OWNDATA : True WRITEABLE : True ALIGNED : True WRITEBACKIFCOPY : False
在构建一个数组的视图时,要记住结果不一定是连续的:
In [236]: arr_c[:50].flags.contiguous Out[236]: True In [237]: arr_c[:, :50].flags Out[237]: C_CONTIGUOUS : False F_CONTIGUOUS : False OWNDATA : False WRITEABLE : True ALIGNED : True WRITEBACKIFCOPY : False
- 一些数据类型的名称中有下划线。这是为了避免 NumPy 特定类型和 Python 内置类型之间的变量名冲突。
附录 B:关于 IPython 系统的更多内容
原文:
wesmckinney.com/book/ipython
译者:飞龙
此开放访问网络版本的《Python 数据分析第三版》现已作为印刷版和数字版的伴侣提供。如果您发现任何勘误,请在此处报告。请注意,由 Quarto 生成的本站点的某些方面与 O’Reilly 的印刷版和电子书版本的格式不同。
如果您发现本书的在线版本有用,请考虑订购纸质版或无 DRM 的电子书以支持作者。本网站的内容不得复制或再生产。代码示例采用 MIT 许可,可在 GitHub 或 Gitee 上找到。
在第二章:Python 语言基础,IPython 和 Jupyter 笔记本中,我们讨论了使用 IPython shell 和 Jupyter 笔记本的基础知识。在本附录中,我们探索了 IPython 系统中的一些更深层次功能,可以从控制台或 Jupyter 中使用。
B.1 终端键盘快捷键
IPython 有许多用于导航提示的键盘快捷键(这些快捷键对于 Emacs 文本编辑器或 Unix bash shell 的用户来说是熟悉的),并与 shell 的命令历史交互。表 B.1 总结了一些最常用的快捷键。请参阅图 B.1 以查看其中一些示例,如光标移动。
表 B.1:标准 IPython 键盘快捷键
键盘快捷键 | 描述 |
Ctrl-P 或向上箭头 | 在命令历史中向后搜索以当前输入文本开头的命令 |
Ctrl-N 或向下箭头 | 在命令历史中向前搜索以当前输入文本开头的命令 |
Ctrl-R | Readline 风格的反向历史搜索(部分匹配) |
Ctrl-Shift-V | 从剪贴板粘贴文本 |
Ctrl-C | 中断当前正在执行的代码 |
Ctrl-A | 将光标移动到行首 |
Ctrl-E | 将光标移动到行尾 |
Ctrl-K | 从光标处删除文本直到行尾 |
Ctrl-U | 放弃当前行上的所有文本 |
Ctrl-F | 将光标向前移动一个字符 |
Ctrl-B | 将光标向后移动一个字符 |
Ctrl-L | 清屏 |
图 B.1:IPython shell 中一些键盘快捷键的示例
请注意,Jupyter 笔记本有一个完全独立的键盘快捷键集用于导航和编辑。由于这些快捷键的发展速度比 IPython 中的快捷键更快,我鼓励您探索 Jupyter 笔记本菜单中的集成帮助系统。
B.2 关于魔术命令
IPython 中的特殊命令(这些命令不是 Python 本身的一部分)被称为魔术命令。这些命令旨在简化常见任务,并使您能够轻松控制 IPython 系统的行为。魔术命令是以百分号 %
为前缀的任何命令。例如,您可以使用 %timeit
魔术函数检查任何 Python 语句(如矩阵乘法)的执行时间:
In [20]: a = np.random.standard_normal((100, 100)) In [20]: %timeit np.dot(a, a) 92.5 µs ± 3.43 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
魔术命令可以被视为在 IPython 系统中运行的命令行程序。其中许多具有额外的“命令行”选项,所有这些选项都可以使用 ?
查看(正如您可能期望的那样):
In [21]: %debug? Docstring: :: %debug [--breakpoint FILE:LINE] [statement [statement ...]] Activate the interactive debugger. This magic command support two ways of activating debugger. One is to activate debugger before executing code. This way, you can set a break point, to step through the code from the point. You can use this mode by giving statements to execute and optionally a breakpoint. The other one is to activate debugger in post-mortem mode. You can activate this mode simply running %debug without any argument. If an exception has just occurred, this lets you inspect its stack frames interactively. Note that this will always work only on the last traceback that occurred, so you must call this quickly after an exception that you wish to inspect has fired, because if another one occurs, it clobbers the previous one. If you want IPython to automatically do this on every exception, see the %pdb magic for more details. .. versionchanged:: 7.3 When running code, user variables are no longer expanded, the magic line is always left unmodified. positional arguments: statement Code to run in debugger. You can omit this in cell magic mode. optional arguments: --breakpoint <FILE:LINE>, -b <FILE:LINE> Set break point at LINE in FILE.
魔术函数可以默认使用,无需百分号,只要没有定义与所讨论的魔术函数同名的变量。这个功能称为自动魔术,可以通过 %automagic
启用或禁用。
一些魔术函数的行为类似于 Python 函数,它们的输出可以分配给一个变量:
In [22]: %pwd Out[22]: '/home/wesm/code/pydata-book' In [23]: foo = %pwd In [24]: foo Out[24]: '/home/wesm/code/pydata-book'
由于 IPython 的文档可以从系统内部访问,我鼓励您使用%quickref
或%magic
来探索所有可用的特殊命令。此信息显示在控制台分页器中,因此您需要按q
键退出分页器。表 B.2 突出显示了在 IPython 中进行交互式计算和 Python 开发时最关键的一些命令。
表 B.2:一些经常使用的 IPython 魔术命令
命令 | 描述 |
%quickref |
显示 IPython 快速参考卡 |
%magic |
显示所有可用魔术命令的详细文档 |
%debug |
进入最后一个异常回溯底部的交互式调试器 |
%hist |
打印命令输入(和可选输出)历史记录 |
%pdb |
在任何异常后自动进入调试器 |
%paste |
从剪贴板执行预格式化的 Python 代码 |
%cpaste |
打开一个特殊提示,用于手动粘贴要执行的 Python 代码 |
%reset |
删除交互式命名空间中定义的所有变量/名称 |
%page |
对对象进行漂亮打印并通过分页器显示 |
%run <script.py> |
在 IPython 内部运行 Python 脚本 |
%prun |
使用cProfile 执行并报告分析器输出 |
%time |
报告单个语句的执行时间 |
%timeit |
多次运行语句以计算集合平均执行时间;用于计时执行时间非常短的代码 |
%who, %who_ls, %whos |
显示交互式命名空间中定义的变量,具有不同级别的信息/详细程度 |
%xdel |
删除变量并尝试清除 IPython 内部对该对象的任何引用 |
%run 命令
您可以使用%run
命令在 IPython 会话的环境中运行任何文件作为 Python 程序。假设您在script.py中存储了以下简单脚本:
def f(x, y, z): return (x + y) / z a = 5 b = 6 c = 7.5 result = f(a, b, c)
您可以通过将文件名传递给%run
来执行此操作:
In [14]: %run script.py
脚本在空命名空间中运行(没有导入或其他变量定义),因此行为应与在命令行上使用python script.py
运行程序相同。然后,文件中定义的所有变量(导入、函数和全局变量)(直到引发异常(如果有))将在 IPython shell 中可访问:
In [15]: c Out [15]: 7.5 In [16]: result Out[16]: 1.4666666666666666
如果 Python 脚本需要命令行参数(可以在sys.argv
中找到),这些参数可以在文件路径之后传递,就像在命令行上运行一样。
注意
如果要让脚本访问已在交互式 IPython 命名空间中定义的变量,请使用%run -i
而不是普通的%run
。
在 Jupyter 笔记本中,您还可以使用相关的%load
魔术函数,它将脚本导入到代码单元格中:
In [16]: %load script.py def f(x, y, z): return (x + y) / z a = 5 b = 6 c = 7.5 result = f(a, b, c)
中断运行的代码
在运行任何代码时按下 Ctrl-C,无论是通过%run
运行脚本还是长时间运行的命令,都会引发KeyboardInterrupt
。这将导致几乎所有 Python 程序立即停止,除非在某些不寻常的情况下。
警告:
当一段 Python 代码调用了一些编译的扩展模块时,按下 Ctrl-C 并不总是会立即停止程序执行。在这种情况下,您要么等待控制返回到 Python 解释器,要么在更严重的情况下,在您的操作系统中强制终止 Python 进程(例如在 Windows 上使用任务管理器或在 Linux 上使用kill
命令)。
从剪贴板执行代码
如果您正在使用 Jupyter 笔记本,您可以将代码复制粘贴到任何代码单元格中并执行。还可以在 IPython shell 中从剪贴板运行代码。假设您在其他应用程序中有以下代码:
x = 5 y = 7 if x > 5: x += 1 y = 8
最可靠的方法是%paste
和%cpaste
魔术函数(请注意,这些在 Jupyter 中不起作用,因为您可以将文本复制并粘贴到 Jupyter 代码单元格中)。%paste
获取剪贴板中的文本并将其作为单个块在 shell 中执行:
In [17]: %paste x = 5 y = 7 if x > 5: x += 1 y = 8 ## -- End pasted text --
%cpaste
类似,只是它为您提供了一个特殊的提示符,用于粘贴代码:
In [18]: %cpaste Pasting code; enter '--' alone on the line to stop or use Ctrl-D. :x = 5 :y = 7 :if x > 5: : x += 1 : : y = 8 :--
使用%cpaste
块,您可以在执行代码之前粘贴尽可能多的代码。您可能决定使用%cpaste
在执行代码之前查看粘贴的代码。如果您意外粘贴了错误的代码,可以通过按 Ctrl-C 键来退出%cpaste
提示符。
B.3 使用命令历史
IPython 维护一个小型的磁盘数据库,其中包含您执行的每个命令的文本。这有各种用途:
- 使用最少的键入搜索、完成和执行先前执行的命令
- 在会话之间保留命令历史
- 将输入/输出历史记录记录到文件中
这些功能在 shell 中比在笔记本中更有用,因为笔记本通过设计在每个代码单元格中保留输入和输出的日志。
搜索和重用命令历史记录
IPython shell 允许您搜索和执行以前的代码或其他命令。这很有用,因为您经常会发现自己重复执行相同的命令,例如%run
命令或其他代码片段。假设您已运行:
In[7]: %run first/second/third/data_script.py
然后探索脚本的结果(假设它成功运行),只发现您进行了错误的计算。找出问题并修改data_script.py后,您可以开始键入%run
命令的几个字母,然后按下 Ctrl-P 键组合或向上箭头键。这将搜索命令历史记录,找到与您键入的字母匹配的第一个先前命令。多次按下 Ctrl-P 或向上箭头键将继续搜索历史记录。如果您错过了要执行的命令,不要担心。您可以通过按下 Ctrl-N 或向下箭头键来向前浏览命令历史记录。几次这样做后,您可能会开始在不经思考的情况下按下这些键!
使用 Ctrl-R 会为您提供与 Unix 风格 shell 中使用的readline
相同的部分增量搜索功能,例如 bash shell。在 Windows 上,IPython 通过模拟readline
功能来实现。要使用此功能,请按 Ctrl-R,然后键入要搜索的输入行中包含的几个字符:
In [1]: a_command = foo(x, y, z) (reverse-i-search)`com': a_command = foo(x, y, z)
按下 Ctrl-R 将循环遍历每行的历史记录,匹配您键入的字符。
输入和输出变量
忘记将函数调用的结果分配给变量可能非常恼人。IPython 会将输入命令和输出 Python 对象的引用存储在特殊变量中。前两个输出分别存储在_
(一个下划线)和__
(两个下划线)变量中:
In [18]: 'input1' Out[18]: 'input1' In [19]: 'input2' Out[19]: 'input2' In [20]: __ Out[20]: 'input1' In [21]: 'input3' Out[21]: 'input3' In [22]: _ Out[22]: 'input3'
输入变量存储在名为_iX
的变量中,其中X
是输入行号。
对于每个输入变量,都有一个相应的输出变量_X
。因此,在输入行 27 之后,将有两个新变量,_27
(用于输出)和_i27
(用于输入):
In [26]: foo = 'bar' In [27]: foo Out[27]: 'bar' In [28]: _i27 Out[28]: u'foo' In [29]: _27 Out[29]: 'bar'
由于输入变量是字符串,因此可以使用 Python 的eval
关键字再次执行它们:
In [30]: eval(_i27) Out[30]: 'bar'
在这里,_i27
指的是In [27]
中输入的代码。
几个魔术函数允许您使用输入和输出历史记录。%hist
打印全部或部分输入历史记录,带或不带行号。%reset
清除交互式命名空间,可选地清除输入和输出缓存。%xdel
魔术函数从 IPython 机制中删除对特定对象的所有引用。有关这些魔术的更多详细信息,请参阅文档。
警告:
在处理非常大的数据集时,请记住 IPython 的输入和输出历史可能导致其中引用的对象不会被垃圾回收(释放内存),即使您使用del
关键字从交互式命名空间中删除变量。在这种情况下,谨慎使用%xdel
和%reset
可以帮助您避免遇到内存问题。
B.4 与操作系统交互
IPython 的另一个特性是它允许您访问文件系统和操作系统 shell。这意味着,您可以像在 Windows 或 Unix(Linux,macOS)shell 中一样执行大多数标准命令行操作,而无需退出 IPython。这包括 shell 命令、更改目录以及将命令的结果存储在 Python 对象(列表或字符串)中。还有命令别名和目录标记功能。
查看表 B.3 以获取调用 shell 命令的魔术函数和语法摘要。我将在接下来的几节中简要介绍这些功能。
表 B.3:IPython 与系统相关的命令
命令 | 描述 |
!cmd |
在系统 shell 中执行cmd |
output = !cmd args |
运行cmd 并将 stdout 存储在output 中 |
%alias alias_name cmd |
为系统(shell)命令定义别名 |
%bookmark |
使用 IPython 的目录标记系统 |
%cd |
将系统工作目录更改为传递的目录 |
%pwd |
返回当前系统工作目录 |
%pushd |
将当前目录放入堆栈并切换到目标目录 |
%popd |
切换到堆栈顶部弹出的目录 |
%dirs |
返回包含当前目录堆栈的列表 |
%dhist |
打印访问过的目录的历史记录 |
%env |
将系统环境变量作为字典返回 |
%matplotlib |
配置 matplotlib 集成选项 |
Python 数据分析(PYDA)第三版(七)(4)https://developer.aliyun.com/article/1482404