热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

20个不常见却很有用的Numpy函数

‍文章来源:https:medium.com推荐阅读:终于来了,【第三期】彭涛Python爬虫特训营!!Numpy是每个数据

文章来源:https://medium.com/

推荐阅读:终于来了,【第三期】 彭涛Python 爬虫特训营!!

Numpy是每个数据科学家都应该掌握的Python包,它提供了许多创建和操作数字数组的方法。它构成了许多与数据科学相关的广泛使用的Python库的基础,比如panda和Matplotlib。

以下这些函数并不常见,甚至你可能都没听说过,但是在有些时候它们真的很有用。

np.full_like

我敢打赌,你肯定使用过像ones_like 或 zeros_like 这样的常见 NumPy 函数。full_like 和这两个完全一样,除了你可以创建一个与另一个矩阵具有相同形状的矩阵但是这些矩阵是使用自定义值填充的。

array = np.array([[1, 4, 6, 8], [9, 4, 4, 4], [2, 7, 2, 3]]) array_w_inf = np.full_like(array, fill_value=np.pi, dtype=np.float32)array_w_inf

array([[3.1415927, 3.1415927, 3.1415927, 3.1415927], [3.1415927, 3.1415927, 3.1415927, 3.1415927], [3.1415927, 3.1415927, 3.1415927, 3.1415927]], dtype=float32)

在这里,我们正在创建一个数组值都是pi 矩阵。

np.logspace

我相信你经常使用linspace。它可以在一个区间内创建自定义的线性间隔数据点数量。它的同类logspace在这方面做得更深入一些。它可以在对数尺度上生成均匀间隔的自定义点数。你可以选择任何一个数作为基数,只要它是非零的:

log_array = np.logspace(start=1, stop=100, num=15, base=np.e) 
log_array

array([2.71828183e+00, 3.20167238e+03, 3.77102401e+06, 4.44162312e+09, 5.23147450e+12, 6.16178472e+15, 7.25753148e+18, 8.54813429e+21, 1.00682443e+25, 1.18586746e+28, 1.39674961e+31, 1.64513282e+34, 1.93768588e+37, 2.28226349e+40, 2.68811714e+43])

np.meshgrid

这是只有在文档中才能看到的函数之一。因为大部分人难理解它。可以使用meshgrid从给定的X和Y数组创建每个可能的坐标对。这里有一个简单的例子:

x = [1, 2, 3, 4] 
y = [3, 5, 6, 8] xx, yy = np.meshgrid(x, y) 
xx

array([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]])

yy

array([[3, 3, 3, 3], [5, 5, 5, 5], [6, 6, 6, 6], [8, 8, 8, 8]])

得到 16 个唯一坐标对,结果数组中的每个索引到索引元素对对应一个。可视化一下就很好理解了

plt.plot(xx, yy, linestyle="none", marker="o", color="red");96fbd23ee7905528c32711ee24751b96.png

meshgrid通常用于使用循环需要很长时间的复杂任务。如绘制三维正弦函数等高线图就是一个例子:

def sinus2d(x, y): return np.sin(x) + np.sin(y) xx, yy = np.meshgrid(np.linspace(0, 2 * np.pi, 100), np.linspace(0, 2 * np.pi, 100)) 
z = sinus2d(xx, yy)  # Create the image on this grid import matplotlib.pyplot as plt plt.imshow(z, origin="lower", interpolation="none") 
plt.show()

93058d9c9d201bd0e132811e9894b1ac.png

np.triu / np.tril

与ones_like或zeros_like类似,这两个函数在矩阵的某个对角线上方或下方返回0。例如,我们可以使用triu函数在主对角线上创建一个值为True的布尔掩码,并在绘制相关热图时使用这个掩码。

import seaborn as snsdiamonds = sns.load_dataset("diamonds")matrix = diamonds.corr()
mask = np.triu(np.ones_like(matrix, dtype=bool))sns.heatmap(matrix, square=True, mask=mask, annot=True, fmt=".2f", center=0);

51036245694e59698525948f268a169d.png

如你所见,用triu创建的掩码可以用在相关矩阵上,去掉不必要的上三角形和对角线。这使得热图更加紧凑,可读性更强。

np.ravel / np.flatten

NumPy是关于高维矩阵和ndarrays的。但是有时候你只是想把这些数组压缩成一维。这就是你使用ravel或flatten的地方:

array = np.random.randint(0, 10, size=(4, 5)) 
array

array([[6, 4, 8, 9, 6], [5, 0, 4, 8, 5], [1, 3, 1, 0, 3], [2, 3, 3, 6, 5]])

array.ravel()

array([6, 4, 8, 9, 6, 5, 0, 4, 8, 5, 1, 3, 1, 0, 3, 2, 3, 3, 6, 5])

array.flatten()

array([6, 4, 8, 9, 6, 5, 0, 4, 8, 5, 1, 3, 1, 0, 3, 2, 3, 3, 6, 5])

它们看起来一样吗?不完全是。flatten总是返回一个1D副本,而ravel则试图生成原始数组的1D视图。也就是说如果修改从ravel返回的数组可能会改变原来的数组。

np.vstack / np.hstack

在Kaggle上这两个函数经常被使用。通常人们从不同的模型对测试集有多个预测,他们希望以某种方式集成这些预测。为了使它们易于处理,必须将它们组合成一个矩阵。

array1 = np.arange(1, 11).reshape(-1, 1)
array2 = np.random.randint(1, 10, size=10).reshape(-1, 1)
hstacked = np.hstack((array1, array2))
hstacked

array([[ 1, 2],[ 2, 6],[ 3, 6],[ 4, 7],[ 5, 4],[ 6, 6],[ 7, 6],[ 8, 8],[ 9, 2],[10, 8]])

array1 = np.arange(20, 31).reshape(1, -1)
array2 = np.random.randint(20, 31, size=11).reshape(1, -1)
vstacked = np.vstack((array1, array2))
vstacked

array([[20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],[21, 23, 23, 26, 29, 26, 27, 27, 28, 25, 25]])

在将每个数组与这些数组堆叠之前,要对数组进行重塑,因为默认情况下它们需要2D数组。这就是我们使用重塑函数的原因。这里,reshape(-1,1)表示将数组转换为具有尽可能多行的单列。

类似地,reshape(1,-1)将数组转换为具有尽可能多列的单行向量。

np.r_ / np.c_

如果你像我一样懒惰,不想对所有数组调用重塑,那么有一个更优雅的解决方案。np.r_ / np.c_操作符(不是函数!)允许将数组分别堆叠为行和列。

下面,我们模拟一个有100个可能性的预测数组。为了将它们堆叠在一起,我们调用np.r_用括号表示(如pandas.DataFrame.loc)。

preds1 = np.random.rand(100)
preds2 = np.random.rand(100)as_rows = np.r_[preds1, preds2]
as_cols = np.c_[preds1, preds2]as_rows.shape

(200,)

as_cols.shape

(100, 2)

类似地,np.c_将数组堆叠在一起创建一个矩阵。其实它们的功能并不局限于简单的水平和垂直堆栈。要了解更多的功能,我建议你阅读文档。http://np.info

NumPy的函数非常的多。你可能没有时间和耐心学习每个函数和类。如果你面对一个未知的函数呢?你不用去看文档了因为有更好的选择。

info函数可以打印NumPy API中任何名称的docstring。这里是info使用的信息:

np.info(np.info)

info(object=None, maxwidth=76, output=, toplevel='numpy') Get help information for a function, class, or module. Parameters 
---------- 
object : object or str, optional Input object or name to get information about. If `object` is a numpy object, its docstring is given. If it is a string, available modules are searched for matching objects.  If None, information about `info` itself is returned. 
maxwidth : int, optional Printing width.

还记得我们在vscode的文章中说过lint要求强制编写docstring吗,这就是原因了。

np.where

顾名思义,这个函数返回一个条件为True的数组的所有下标:

probs = np.random.rand(100) 
idx = np.where(probs > 0.8) probs[idx]

array([0.80444302, 0.80623093, 0.98833642, 0.96856382, 0.89329919, 0.88664223, 0.90515148, 0.96363973, 0.81847588, 0.88250337, 0.98737432, 0.92104315])

它在搜索稀疏数组中的非零元素时特别有用,甚至可以在Pandas DataFrames上使用它来基于条件进行更快的索引检索。

np.all / np.any

当与assert语句一起使用时,这两个函数将在数据清理期间非常方便。np.all仅当数组中的所有元素都符合特定条件时返回True:

array1 = np.random.rand(100)
array2 = np.random.rand(100)>>> np.all(array1 == array2)
False

因为我们创建了两个随机数的数组,所以不可能每个元素都相等。然而,如果这些数字是整数,那么它们中至少有两个相等的可能性要大得多:

a1 = np.random.randint(1, 100, size=100)
a2 = np.random.randint(1, 100, size=100)>>> np.any(a1 == a2)
True

any返回True是因为数组中至少有一个元素满足特定条件,

np.allclose

如果想要检查两个长度相等的数组是否互为副本,简单的==操作符不会将其截断。但是你可能想要比较浮点数数组,但是它们的小数点长度使得比较困难。在这种情况下可以使用allclose,如果一个数组的所有元素彼此之间距离很近,给定一定的容忍度,它将返回True。

a1 = np.arange(1, 10, step=0.5) 
a2 = np.arange(0.8, 9.8, step=0.5) np.all(a1 == a2)

False

a1

array([1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. , 5.5, 6. , 6.5, 7. , 7.5, 8. , 8.5, 9. , 9.5])

a2

array([0.8, 1.3, 1.8, 2.3, 2.8, 3.3, 3.8, 4.3, 4.8, 5.3, 5.8, 6.3, 6.8, 7.3, 7.8, 8.3, 8.8, 9.3])

np.allclose(a1, a2, rtol=0.2)

False

np.allclose(a1, a2, rtol=0.3)

True

只有当差异(<)小于rtol时&#xff0c;函数才返回True&#xff0c;而不是<&#61;!

np.argsort

np.sort返回一个已排序的数组副本。有时需要对数组进行排序的索引&#xff0c;以便为不同的目的多次使用相同的索引。这就是 argsort 派上用场的地方&#xff1a;

random_ints &#61; np.random.randint(1, 100, size&#61;20) 
idx &#61; np.argsort(random_ints) random_ints[idx]

array([ 6, 19, 22, 23, 35, 36, 37, 45, 46, 57,61, 62, 64, 66, 66, 68, 72, 74, 87, 89])

它来自以 arg 开头的一系列函数&#xff0c;这些函数总是从某个函数的结果返回一个或多个索引。例如&#xff0c;argmax 查找数组中的最大值并返回其索引&#xff08;分类的TOP N就可以用这种方法&#xff09;。

np.isneginf / np.isposinf

这两个布尔函数检查数组中的元素是负无穷大还是正无穷大。但是计算机和 NumPy 不理解无穷大的概念&#xff08;好吧&#xff0c;我也不知道是为什么&#xff09;。它们只能将无穷大表示为一个非常大或非常小的数字&#xff0c;这样才可以放入一个变量中&#xff08;我希望我说得对&#xff09;。

这就是为什么当你打印 np.inf 的类型时&#xff0c;它返回浮点数&#xff1a;

type(np.inf)  # type of the infinity

float

type(-np.inf)

float

这意味着无穷大值可以很容易地被当作数组的正常值。所以你需要一个特殊的功能来找到这些异常的值&#xff1a;

a &#61; np.array([-9999, 99999, 97897, -79897, -np.inf]) np.all(a.dtype &#61;&#61; "float64")

True

np.any(np.isneginf(a))

True

np.polyfit

如果要执行传统的线性回归&#xff0c;则不一定需要 Sklearn。NumPy 也可以的&#xff1a;

X &#61; diamonds["carat"].values.flatten() 
y &#61; diamonds["price"].values.flatten() slope, intercept &#61; np.polyfit(X, y, deg&#61;1) 
slope, intercept

(7756.425617968436, -2256.3605800454034)

polyfit 获取两个向量&#xff0c;对它们应用线性回归并返回斜率和截距。你只需要使用 deg 指定次数&#xff0c;因为此函数可用于逼近任何次数多项式的根。

检查发现用 polyfit 找到的斜率和截距与 Sklearn 的 LinearRegression 模型相同&#xff1a;

from sklearn.linear_model import LinearRegression lr &#61; LinearRegression().fit(X.reshape(-1, 1), y) 
lr.coef_, lr.intercept_

(array([7756.42561797]), -2256.360580045441)

概率分布

NumPy 的 random 模块有多种伪随机数生成器可供选择。除了我最喜欢的样本和选择之外&#xff0c;还有模拟伪完美概率分布的函数。

例如&#xff0c;二项式、伽马、正态和 tweedie 函数从它们各自的分布中绘制自定义数量的数据点。

当你必须近似数据中特征的分布时&#xff0c;你可能会发现它们非常有用。例如&#xff0c;下面我们检查钻石价格是否服从正态分布。

fig, ax &#61; plt.subplots(figsize&#61;(6, 8)) price_mean &#61; diamonds["price"].mean() 
price_std &#61; diamonds["price"].std() # Draw from a perfect normal distribution 
perfect_norm &#61; np.random.normal(price_mean, price_std, size&#61;1000000) sns.kdeplot(diamonds["price"], ax&#61;ax) 
sns.kdeplot(perfect_norm, ax&#61;ax) plt.legend(["Price", "Perfect Normal Distribution"]);
20a76d91f40c2ffd29701c39e74bb391.png

这可以通过在完美正态分布之上绘制钻石价格的 KDE 来实现&#xff0c;以使差异可见。

np.rint

如果你想将数组的每个元素四舍五入到最接近的整数&#xff0c; rint 是一个漂亮的小函数。当你想将类概率转换为二进制分类中的类标签时&#xff0c;可以不必调用模型的 predict 方法改成直接使用它&#xff1a;

preds &#61; np.random.rand(100) 
np.rint(preds[:50])

array([1., 1., 0., 1., 0., 1., 1., 0., 0., 0., 0., 1., 0., 1., 0., 1., 0., 1., 0., 1., 1., 1., 1., 1., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 1., 0., 1., 1., 0., 0., 1., 0.])

np.nanmean / np.nan*

是否知道如果至少有一个元素是 NaN&#xff0c;则纯 NumPy 数组上的算术运算会失败&#xff1f;

a &#61; np.array([12, 45, np.nan, 9, np.nan, 22]) 
np.mean(a)

nan

要在不修改原始数组的情况下解决此问题&#xff0c;你可以使用一系列 nan 函数&#xff1a;

np.nanmean(a)

22.0

以上是忽略缺失值的算术平均函数的示例。许多其他函数以同样的方式工作&#xff1a;

[func for func in dir(np) if func.startswith("nan")]

[&#39;nan&#39;, &#39;nan_to_num&#39;, &#39;nanargmax&#39;, &#39;nanargmin&#39;, &#39;nancumprod&#39;, &#39;nancumsum&#39;, &#39;nanmax&#39;, &#39;nanmean&#39;, &#39;nanmedian&#39;, &#39;nanmin&#39;, &#39;nanpercentile&#39;, &#39;nanprod&#39;, &#39;nanquantile&#39;, &#39;nanstd&#39;, &#39;nansum&#39;, &#39;nanvar&#39;]

但是&#xff0c;如果只使用 Pandas DataFrames 或 Series&#xff0c;可能会有些不同&#xff0c;因为它们默认会忽略 NaN。

np.clip

当想对数组的值施加严格限制时&#xff0c;clip 很有用。下面&#xff0c;我们将裁剪任何超出 10 和 70 硬限制的值&#xff1a;

ages &#61; np.random.randint(1, 110, size&#61;100) 
limited_ages &#61; np.clip(ages, 10, 70) 
limited_ages

array([13, 70, 10, 70, 70, 10, 63, 70, 70, 69, 45, 70, 70, 56, 60, 70, 70, 10, 52, 70, 32, 62, 21, 70, 13, 13, 10, 50, 38, 32, 70, 20, 27, 64, 34, 10, 70, 70, 53, 70, 53, 54, 26, 70, 57, 70, 46, 70, 17, 48, 70, 15, 49, 70, 10, 70, 19, 23, 70, 70, 70, 45, 47, 70, 70, 34, 25, 70, 10, 70, 42, 62, 70, 10, 70, 23, 25, 49, 70, 70, 62, 70, 70, 11, 10, 70, 30, 44, 70, 49, 10, 35, 52, 21, 70, 70, 25, 10, 55, 59])

np.count_nonzero

使用稀疏数组是很常见的。通常&#xff0c;它们是对具有高基数(High-Cardinality)或只有许多二进制列的分类特征进行独热编码的结果。

你可以使用count_nonzero来检查任意数组中非零元素的数量:

a &#61; np.random.randint(-50, 50, size&#61;100000) 
np.count_nonzero(a)

98993

100k 随机整数中&#xff0c;~1000个为零。

np.array_split

它可以用来将 ndarray 或 dataframe 分成 N 个 bucket。此外&#xff0c;当你想要将数组分割成大小不相等的块(如 vsplit )时&#xff0c;它不会引发错误:

import datatable as dt 
df &#61; dt.fread("data/train.csv").to_pandas() 
splitted_dfs &#61; np.array_split(df, 100) 
len(splitted_dfs)

我们爬虫第三期来了&#xff0c;加入我们&#xff0c;学更实用&#xff0c;更值钱的 Python 技术&#xff01;

从0到1系统掌握Python 技术&#xff08;入门进阶&#xff09;
2个企业实战项目&#xff0c;4大常用工具
掌握24种反爬策略手段&#xff0c;成为真正爬虫高手
能抓取市面上90%的网站
掌握主流爬虫技术&#xff0c;就业找工作 真正全方位帮助大家从0到1&#xff0c;从 Python 入门到进阶&#xff0c;转行找爬虫工作。


推荐阅读
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 无损压缩算法专题——LZSS算法实现
    本文介绍了基于无损压缩算法专题的LZSS算法实现。通过Python和C两种语言的代码实现了对任意文件的压缩和解压功能。详细介绍了LZSS算法的原理和实现过程,以及代码中的注释。 ... [详细]
  • 解决python matplotlib画水平直线的问题
    本文介绍了在使用python的matplotlib库画水平直线时可能遇到的问题,并提供了解决方法。通过导入numpy和matplotlib.pyplot模块,设置绘图对象的宽度和高度,以及使用plot函数绘制水平直线,可以解决该问题。 ... [详细]
  • 本文介绍了在Python中使用zlib模块进行字符串的压缩与解压缩的方法,并探讨了其在内存优化方面的应用。通过压缩存储URL等长字符串,可以大大降低内存消耗,虽然处理时间会增加,但是整体效果显著。同时,给出了参考链接,供进一步学习和应用。 ... [详细]
  • EzPP 0.2发布,新增YAML布局渲染功能
    EzPP发布了0.2.1版本,新增了YAML布局渲染功能,可以将YAML文件渲染为图片,并且可以复用YAML作为模版,通过传递不同参数生成不同的图片。这个功能可以用于绘制Logo、封面或其他图片,让用户不需要安装或卸载Photoshop。文章还提供了一个入门例子,介绍了使用ezpp的基本渲染方法,以及如何使用canvas、text类元素、自定义字体等。 ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • 开源Keras Faster RCNN模型介绍及代码结构解析
    本文介绍了开源Keras Faster RCNN模型的环境需求和代码结构,包括FasterRCNN源码解析、RPN与classifier定义、data_generators.py文件的功能以及损失计算。同时提供了该模型的开源地址和安装所需的库。 ... [详细]
  • Python使用Pillow包生成验证码图片的方法
    本文介绍了使用Python中的Pillow包生成验证码图片的方法。通过随机生成数字和符号,并添加干扰象素,生成一幅验证码图片。需要配置好Python环境,并安装Pillow库。代码实现包括导入Pillow包和随机模块,定义随机生成字母、数字和字体颜色的函数。 ... [详细]
  • Python教学练习二Python1-12练习二一、判断季节用户输入月份,判断这个月是哪个季节?3,4,5月----春 ... [详细]
  • 本文介绍了Python对Excel文件的读取方法,包括模块的安装和使用。通过安装xlrd、xlwt、xlutils、pyExcelerator等模块,可以实现对Excel文件的读取和处理。具体的读取方法包括打开excel文件、抓取所有sheet的名称、定位到指定的表单等。本文提供了两种定位表单的方式,并给出了相应的代码示例。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • 本文介绍了使用Python解析C语言结构体的方法,包括定义基本类型和结构体类型的字典,并提供了一个示例代码,展示了如何解析C语言结构体。 ... [详细]
author-avatar
mobiledu2502897737
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有