从Python到NumPy,细说最接近人类思维的in操作

开发 后端
在Python语言中,in是一个使用频率非常高的操作符,用于判断对象是否位于字符串、元组、列表、集合或字典中。in操作和人的思维方式高度吻合,写起来近乎于自然语言,充分体现了Python的哲学理念。

[[397119]]

本文转载自微信公众号「 Python作业辅导员」,作者天元浪子 。转载本文请联系 Python作业辅导员公众号。

在Python语言中,in是一个使用频率非常高的操作符,用于判断对象是否位于字符串、元组、列表、集合或字典中。in操作和人的思维方式高度吻合,写起来近乎于自然语言,充分体现了Python的哲学理念。

  1. >>> 'or' in 'hello world' 
  2. True 
  3. >>> 5 in {1,2,3,4} 
  4. False 
  5. >>> 'age' in {'name':'Mike''age':18} 
  6. True 

有趣的是,除了R、javascript、SQL外,包括C/C++在内的主流语言几乎都不支持in操作。这或许可以解释为什么Python语言被认为是最容易学习的编程语言。

习惯了使用Python的in操作符,有时就会自然而然地应用到NumPy数组操作上。比如,下面的写法看起来没有任何问题。

  1. >>> import numpy as np 
  2. >>> a = np.arange(9) 
  3. >>> a 
  4. array([0, 1, 2, 3, 4, 5, 6, 7, 8]) 
  5. >>> 5 in a 
  6. True 
  7. >>> 10 in a 
  8. False 

不过,当我尝试在np.where()函数中使用in操作符的时候,出现了意外。

  1. >>> np.where(a>5) 
  2. (array([6, 7, 8], dtype=int64),) 
  3. >>> np.where(a%2==0) 
  4. (array([0, 2, 4, 6, 8], dtype=int64),) 
  5. >>> np.where(a in [2,3,5,7]) 
  6. Traceback (most recent call last): 
  7.   File "<pyshell#111>", line 1, in <module> 
  8.     np.where(a in [2,3,5,7]) 
  9. ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

使用a>5或者a%2==0作为条件,np.where()函数没有问题,但是,使用a in [2,3,5,7],np.where()就会抛出异常。即便写成下面这样,也不能得到期望的结果。

  1. >>> np.where(a in np.array([2,3,5,7])) 
  2. (array([], dtype=int64),) 

难道NumPy不支持两个数组之间的in操作吗?不,强大到宇宙无敌的NumPy,怎么会不支持数组之间的in操作呢?NumPy不但支持,而且支持得很好。

  1. >>> p = np.array([2,3,5,7]) # 质数数组 
  2. >>> np.in1d(a, p) # 返回a的每一个元素是否是质数的布尔数组 
  3. array([FalseFalse,  True,  TrueFalse,  TrueFalse,  TrueFalse]) 
  4. >>> np.where(np.in1d(a, p)) # 返回数组a中质数的索引序号 
  5. (array([2, 3, 5, 7], dtype=int64),) 
  6. >>> np.where(np.in1d(a, p), -1, a) # 返回数组a中的质数全部替换为-1的结果 
  7. array([ 0,  1, -1, -1,  4, -1,  6, -1,  8]) 

np.in1d()的参数如果是多维数组,将被自动扁平化,且返回的布尔数组也是扁平化的一维数组。

  1. >>> np.in1d(a.reshape((3,3)), p) 
  2. array([FalseFalse,  True,  TrueFalse,  TrueFalse,  TrueFalse]) 

如果np.in1d()的参数是多维的,且期望返回和原数组结构相同的布尔数组,则应使用np.isin()函数。

  1. >>> np.isin(a.reshape((3,3)), p) 
  2. array([[FalseFalse,  True], 
  3.        [ TrueFalse,  True], 
  4.        [False,  TrueFalse]]) 
  5. >>> np.where(np.isin(a.reshape((3,3)), p)) 
  6. (array([0, 1, 1, 2], dtype=int64), array([2, 0, 2, 1], dtype=int64)) 

若是期望得到两个数组的交集而不是交集元素的索引,下面两种方式都可行。

  1. >>> a[np.where(np.isin(a, p))] 
  2. array([2, 3, 5, 7]) 
  3. >>> np.intersect1d(a, p) 
  4. array([2, 3, 5, 7]) 

第二种方式直接使用np.intersect1d()函数得到两个数组的交集,且自动排序。不过,我更喜欢第一种方式。

责任编辑:武晓燕 来源: Python作业辅导员
相关推荐

2022-08-25 10:31:57

模型人工智能

2021-07-19 14:37:04

AI 数据人工智能

2021-12-24 09:01:05

LeetCode三数之和算法

2024-05-20 15:25:47

2023-03-26 21:03:54

GPT-4人工智能

2021-05-07 05:54:43

数据库数据湖数据

2021-10-03 14:37:06

编程语言程序员代码

2019-07-22 15:33:19

计算机互联网 技术

2020-11-16 08:54:05

Google 开源技术

2021-09-11 16:42:26

AndroidAndroid 12

2013-08-20 13:34:02

创业极客

2021-02-28 13:57:51

大数据人工智能信息

2021-03-01 10:43:56

大数据人工智能

2017-11-20 05:41:41

数组矩阵NumPy

2021-07-14 10:39:28

JqueryVue 编程

2016-01-05 09:42:39

2021-07-26 16:08:36

AI Transformer人工智能

2010-02-23 11:18:25

Python 操作符

2021-12-09 15:03:10

人工智能AI人类思维

2022-07-11 11:14:47

强化学习AI基于模型
点赞
收藏

51CTO技术栈公众号