【Python】收集的高级函数、功能

说明:本文更新顺序是从下到上,最新的函数更新在开头。

  • map与reduce
关于二维数组求和的几种方法:

   a = [[1,2],[3,4],[5,6]]
   1.sum(map(sum,a)) #first, map(func,a) 函数是对a中的每一个元素进行sum操作
  解释一下map函数, map(fund, a)   equals
  [func(i) for i in a]  and return a list
   2.sum(sum(i) for i in a) #second one

   3.sum(sum(a[i]) for i in range(len(a))) #third one
   4.reduce(lambda x,y:x+y , reduce(lambda x,y:x+y, a))
     解释一下reduce(fun,a),只不说reduce返回的是一个结果值而不是一个list,第一步的时候是([1,2]+[3,4]) + [5,6]
     得到一个[1,2,3,4,5,6], 然后进行的运算是(((((1+2)+3)+4)+5)+6) = 21

一般来说最常用的还是1和3这两种方法,不知道map or reduce, 一般都会采用3, 而知道的应该会采用1,比较简洁,至于效率方面没有尽兴比较。
  • numpy中的todense与toarray
todense返回矩阵,toarray返回数组
  • numpy.random.choice(a[, size, replace, p])

功能:从一维数组a中以概率p抽取抽取元素,形成size形状新的数组,replace表示是否可以重用元素,默认为True。举例:

np.random.choice([0,1],(2,3), p=[0.1, 0.9])
Out[14]: 
array([[1, 1, 1],
       [1, 1, 1]])
np.random.choice([0,1],(2,3), p=[0.5, 0.5])
Out[15]: 
array([[0, 0, 1],
       [0, 0, 1]])
np.random.choice([0,1],(2,3), p=[0.5, 0.5])
Out[16]: 
array([[0, 1, 0],
       [1, 0, 0]])

  • os.listdir与os.path.splitext(file)
os.listdir:列出所有文件目录;
os.path.splitext(file):获得文件后缀;
os.path.exists(path):判断目录是否存在;

  • python:eval与exec

本来是想打算使用eval函数对变量进行赋值的,没想到出现了invalid syntax错误。源代码如下

?
1
2
3
4
5
In [ 2 ]: eval ( 'a = 1' )
  File "<string>" , line 1
  a = 1
   ^
SyntaxError: invalid syntax

  百度没百度到结果,最后在stackoverflow上找到了好的答案.

  作者的意思是,eval函数只负责对表达式进行处理,并没有赋值的功能,也就是说,eval函数只负责对你的输入进行输出,True还是False又或者是什么东西。但它本身是没有影响当前代码环境的能力的。如果我们想用来进行赋值,那么应该使用exec()函数。看代码:

?
1
2
3
In [ 3 ]: exec ( 'a = 1' )
In [ 4 ]: a
Out[ 4 ]: 1

  问题的解决方案已经供出了,那么我们现在再看看官方文档对这两个函数怎么说。

eval(expression, global=None, local=None)

      参数是字符串和可选的global和local。global应当为一个字典文件,local应为一个映射对象。

  expression参数将被处理为一个python的表达式(严格来说,是一串条件语句),global和local参数将被用来当做全局和局部的命名空间。

exec(object[,global,[locals])

  这个函数能够为python提供动态的代码执行功能。

  • python:makedir与makedirs

多层创建目录函数os.makedirs(path)。这两个函数之间最大的区别是当父目录不存在的时候os.mkdir(path)不会创建,os.makedirs(path)则会创建父目录。

  • python:join

在 python 中,一共有两个 join 方法,一个是 str.join(),另一个是 os.path.join() 

str.join(iterable):将可迭代对象中的元素以 str 为分隔符拼接返回,但是这些元素必须为 String 类型,不然会报错。

注:当要使用大量的字符串拼接时,尽量避免 + 操作,这样会产生大量的临时变量,占据内存,可以先将其拼接到 list 中,然后使用 join 方法

  • np.maximum:将所有元素最小值设为某个数(相反的是np.minimum
>>> a
array([[-4, -4, -5,  2,  1],
       [-1, -2, -1,  3,  3],
       [-1, -2,  3, -5,  3],
       [ 0, -3, -5,  1, -4],
       [ 0,  3,  1,  3, -4]])
# 
>>> np.maximum(a, 0)
array([[0, 0, 0, 2, 1],
       [0, 0, 0, 3, 3],
       [0, 0, 3, 0, 3],
       [0, 0, 0, 1, 0],
       [0, 3, 1, 3, 0]])


  • raise引发异常

当程序出现错误,python会自动引发异常,也可以通过raise显示地引发异常。

一旦执行了raise语句,raise后面的语句将不能执行。演示raise用法

try:
     s = None
     if s is None:
         print "s 是空对象"
         raise NameError     #如果引发NameError异常,后面的代码将不能执行
     print len(s)  #这句不会执行,但是后面的except还是会走到
except TypeError:
     print "空对象没有长度"
 
s = None
if s is None:
    raise NameError
 
print 'is here?' #如果不使用try......except这种形式,那么直接抛出异常,不会执行到这里

raise语法格式如下:

raise [Exception [, args [, traceback]]]

一个异常可以是一个字符串,类或对象。 Python的内核提供的异常,大多数都是实例化的类,这是一个类的实例的参数。

定义一个异常非常简单,如下所示:

def functionName( level ):
    if level < 1:
        raise Exception("Invalid level!", level)
        # 触发异常后,后面的代码就不会再执行

注意:为了能够捕获异常,"except"语句必须有用相同的异常来抛出类对象或者字符串。

例如我们捕获以上异常,"except"语句如下所示:

try:
    正常逻辑
except "Invalid level!":
    触发自定义异常    
else:
    其余代码
  • 集合操作
set集合说复杂不复杂,说简单也不简单。简单见下例:

>>> x = set('spam')  
>>> y = set(['h','a','m'])  
>>> x, y  
(set(['a', 'p', 's', 'm']), set(['a', 'h', 'm']))    
  
>>> x & y # 交集  
set(['a', 'm'])  
  
>>> x | y # 并集  
set(['a', 'p', 's', 'h', 'm'])  
  
>>> x - y # 差集  
set(['p', 's']) 
不简单是因为,当二维list或者numpy数组想要转set时,就会报错。而有些操作如:并集、交集、差集,必须要用set对象操作。

PS:楼主一晚上憋了三行代码:

    [_a, _b, _c] = map(lambda x: np.array(np.where(x != 0)).transpose(), [pos-elem_to_reduce, lbest-pos, gbest-pos])
    [a, b, c] = map(lambda y: set([tuple(it) for it in y]), [_a, _b, _c])
    indices = (b | c) & a

  • np.where

numpy.where函数是三元表达式x if condition else y的矢量化版本。定义一个布尔数组和两个值数组:

>>> xarr=np.array([1.1,1.2,1.3,1.4,1.5])
>>> yarr=np.array([2.1,2.2,2.3,2.4,2.5])
>>> cond=np.array([True,False,True,True,False])
>>> result=[(x for c else y) for x,y,c in zip(xarr,yarr,cond)]
  File "<stdin>", line 1
    result=[(x for c else y) for x,y,c in zip(xarr,yarr,cond)]
                        ^
SyntaxError: invalid syntax
>>> result=[(x if c else y) for x,y,c in zip(xarr,yarr,cond)]
>>> result
[1.1000000000000001, 2.2000000000000002, 1.3, 1.3999999999999999, 2.5]

以上做法有几个问题:第一,速度不够快;第二:无法用于多维数组。若用np.where,则可以将该功能写得非常简洁。

>>> reslut=np.where(cond,xarr,yarr)
>>> result
[1.1000000000000001, 2.2000000000000002, 1.3, 1.3999999999999999, 2.5]

再看一个例子,既能找出位置,又能方便找出元素:

>>> x = np.arange(9.).reshape(3, 3)
>>> np.where( x > 5 )
(array([2, 2, 2]), array([0, 1, 2]))
>>> x[np.where( x > 3.0 )]               # Note: result is 1D.
array([ 4.,  5.,  6.,  7.,  8.])
>>> np.where(x < 5, x, -1)               # Note: broadcasting.
array([[ 0.,  1.,  2.],
       [ 3.,  4., -1.],
       [-1., -1., -1.]])

  • flatten与hstack—— 将numpy 二维数组转一维、或者将数组拉平

b
Out[41]: 
array([[1, 2],
       [3, 4],
       [5, 6]])

b.flatten()
Out[42]: array([1, 2, 3, 4, 5, 6])

b
Out[43]: 
array([[1, 2],
       [3, 4],
       [5, 6]])

注意,当数组列长度不一样时flatten失效。

b
Out[126]: array([[0, 1, 2, 3, 7, 13], [32, 33, 8, 30], [32, 33, 29, 23]], dtype=object)

b.flatten()
Out[127]: array([[0, 1, 2, 3, 7, 13], [32, 33, 8, 30], [32, 33, 29, 23]], dtype=object)
这时应该改为np.hstack()函数

b
Out[128]: array([[0, 1, 2, 3, 7, 13], [32, 33, 8, 30], [32, 33, 29, 23]], dtype=object)

np.hstack(b)
Out[129]: array([ 0,  1,  2, ..., 33, 29, 23])

  • python numpy 改变数组维度
使用数组的reshape方法,可以创建一个改变了尺寸的新数组,原数组的shape保持不变:

>>> d = a.reshape((2,2))
>>> d
array([[1, 2],
       [3, 4]])
>>> a
array([1, 2, 3, 4])
数组a和d其实共享数据存储内存区域,因此修改其中任意一个数组的元素都会同时修改另外一个数组的内容!

>>> a[1] = 100 # 将数组a的第一个元素改为100
>>> d # 注意数组d中的2也被改变了
array([[  1, 100],
       [  3,   4]])
Note: 需要注意的是,这里与MATLAB不一样,MATLAB变换是按列向量来的,而NUMPY是基于行向量。

  • python numpy 数组如何对每个元素进行操作?

问题:python filter 如何应用在numpy array中,比如我有一个二维numpy数组,想将数组中小于0的置零大于零的保留原值,但是不想用for循环,有没有比较高效简洁的方法。

>>> import numpy as np
>>> a = np.random.randint(-5, 5, (5, 5))
>>> a
array([[-4, -4, -5,  2,  1],
       [-1, -2, -1,  3,  3],
       [-1, -2,  3, -5,  3],
       [ 0, -3, -5,  1, -4],
       [ 0,  3,  1,  3, -4]])
# 方式一
>>> np.maximum(a, 0)
array([[0, 0, 0, 2, 1],
       [0, 0, 0, 3, 3],
       [0, 0, 3, 0, 3],
       [0, 0, 0, 1, 0],
       [0, 3, 1, 3, 0]])
# 方式二
>>> (a + abs(a)) / 2
array([[0, 0, 0, 2, 1],
       [0, 0, 0, 3, 3],
       [0, 0, 3, 0, 3],
       [0, 0, 0, 1, 0],
       [0, 3, 1, 3, 0]])
# 方式三
>>> b = a.copy()
>>> b[b < 0] = 0
>>> b
array([[0, 0, 0, 2, 1],
       [0, 0, 0, 3, 3],
       [0, 0, 3, 0, 3],
       [0, 0, 0, 1, 0],
       [0, 3, 1, 3, 0]])
# 方式四
>>> np.where(a > 0, a, 0)
array([[0, 0, 0, 2, 1],
       [0, 0, 0, 3, 3],
       [0, 0, 3, 0, 3],
       [0, 0, 0, 1, 0],
       [0, 3, 1, 3, 0]])
链接:https://www.zhihu.com/question/46988087/answer/115228501

  • python3中的视图

Views(视图)的作用,类似于数据库中视图的一个作用,数据库表变化后,视图查询的结果是变化后的值。python中通过Views查询的值也是这样的。

dict.keys(),dict.items(),dict.values()返回的是Views。

>>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}  
>>> keys = dishes.keys()  
>>> values = dishes.values()  
  
>>> # iteration  
>>> n = 0  
>>> for val in values:  
...     n += val  
>>> print(n)  
504  
  
>>> # keys and values are iterated over in the same order  
>>> list(keys)  
['eggs', 'bacon', 'sausage', 'spam']  
>>> list(values)  
[2, 1, 1, 500]  
  
>>> # view objects are dynamic and reflect dict changes  
>>> del dishes['eggs']  
>>> del dishes['sausage']  
>>> list(keys)  
['spam', 'bacon']  
  
>>> # set operations  
>>> keys & {'eggs', 'bacon', 'salad'}  
{'bacon'}

  • 引入外部文件

(1) 如果引入文件是在子目录,如:

folder

------tobeinvodedA.py

------tobeinvodedB.py

------tobeinvodedC.py

toinvoke.py

这种情况,在folder 下新建一个__init__.py 的空文件,此时的folder不再是一个普通的文件夹,而是一个包 package。现在像这样

folder #文件夹 现在的性质为一个python包package 

------__init__.py

------tobeinvoded.py

------tobeinvodedA.py

------tobeinvodedB.py

------tobeinvodedC.py

toinvoke.py

这样在toinvoke.py 中引入

import folder.toveinvoked 或 from folder.tobeinvoked import *

即可

(2) 如果是外部目录,如folderB中的模块要调用folderA中的模块,方法同上

folderA 

------tobeinvoded.py

------tobeinvodedA.py

------tobeinvodedB.py

------tobeinvodedC.py

folderB 

--------toinvoke.py

这样在toinvoke.py 中引入

import folder.toveinvoked 或 from folder.tobeinvoked import *

即可

(3) Python的包搜索路径

Python会在以下路径中搜索它想要寻找的模块:

  • 程序所在的文件夹
  • 标准库的安装路径
  • 操作系统环境变量PYTHONPATH所包含的路径

将自定义库的路径添加到Python的库路径中去,可以在程序运行过程中修改sys.path的值,动态地添加自己的库路径:

import os,sys 
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 
sys.path.insert(0,parentdir)

sys模块是使用c语言编写的,因此字符串支持 '\n', '\r', '\t'等来表示特殊字符。所以最好写成: sys.path.append('c:\\xxx\\b.py') 避免转义

或者,在Python安装目录下的\Lib\site-packages文件夹中建立一个.pth文件,内容为自己写的库路径。示例如下:

E:\\work\\Python\\http

参考

  • shuffle()随机排序

shuffle() 方法将序列的所有元素随机排序。

random.shuffle 并不返回一个list,而是原地改变。

  • 字典关键字获取的特殊方式
偶然从一个良心bug中发现的

nets = {
        "RG": 1,
        }
for net in nets:
    print(net)
    
RG

  • numpy.zeros()的dtype选项

用法:zeros(shape, dtype=float, order='C')

返回:返回来一个给定形状和类型的用0填充的数组;

参数:shape:形状

            dtype:数据类型,可选参数,默认numpy.float64

            dtype类型:t ,位域,如t4代表4位

                                 b,布尔值,true or false

                                 i,整数,如i8(64位)

                                u,无符号整数,u8(64位)

                                f,浮点数,f8(64位)

                               c,浮点负数,

                                o,对象,

                               s,a,字符串,s24

                               u,unicode,u24

            order:可选参数,c代表与C语言类似,行优先;F代表列优先

  • numpy数组切片和部分赋值

>>>a=np.array([0,0,0,0,0])
>>> b="123"
>>> a[len(a)-len(b):]=list(b)
>>> a
array([0, 0, 1, 2, 3])

  • Python中字符串与数组的转换

['x','y','z'] => 'xyz'
b = ''.join(['x','y','z'])
'xyz' => ['x','y','z']
a = list('xyz')
  • python字符串str和字节数组相互转化

# bytes object    
b = b"example"    
  
# str object    
s = "example"    
  
# str to bytes    
bytes(s, encoding = "utf8")    
  
# bytes to str    
str(b, encoding = "utf-8")    
  
# an alternative method    
# str to bytes    
str.encode(s)    
  
# bytes to str    
bytes.decode(b) 

参考:http://blog.csdn.net/gong_xucheng/article/details/45216721

  • bin —— 十进制转化为二进制

将十进制数转化为二进制,并去除前面标记符:bin(number).replace('0b','')

二进制转化为十进制:int(number, 2)

  • L[::-1]  —— numpy数组倒序

一般形式是seq[start: end: step],由于seq的slice操作带有步长的操作,因此,在设计中可以使用负数作为步长,当step为-1时,指定需要逆序的元素区间,则可以逆序

  • xrange —— 迭代器

range返回的是一个包含所有元素的列表,xrange返回的是一个生成器,生成器是一个可迭代对象,在对生成器进行迭代时,元素是逐个被创建的。一般来看,在对大序列进行迭代的时候,因为xrange的特性,所以它会比较节约内存。

  • numpy.concatenate((a1,a2,...), axis=0) —— numpy拼接多个数组
>>> a=np.array([1,2,3])
>>> b=np.array([11,22,33])
>>> c=np.array([44,55,66])
>>> np.concatenate((a,b,c),axis=0)  # 默认情况下,axis=0可以不写
array([ 1,  2,  3, 11, 22, 33, 44, 55, 66]) #对于一维数组拼接,axis的值不影响最后的结果

 

>>> a=np.array([[1,2,3],[4,5,6]])
>>> b=np.array([[11,21,31],[7,8,9]])
>>> np.concatenate((a,b),axis=0)
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [11, 21, 31],
       [ 7,  8,  9]])

>>> np.concatenate((a,b),axis=1)  #axis=1表示对应行的数组进行拼接
array([[ 1,  2,  3, 11, 21, 31],
       [ 4,  5,  6,  7,  8,  9]])
对numpy.append()和numpy.concatenate()两个函数的运行时间,concatenate()效率更高,适合大规模的数据拼接。
  • 比较[it if else for...] 与 [it for ... if]
 
   
a.remove(0)

a=[1, 1, 2, 0, 0, 1]

b=[index for (index, value) in enumerate(a) if value != 0]

b
Out[396]: [0, 1, 2, 5]

b=[index if value != 0 else -1 for (index, value) in enumerate(a)]

b
Out[398]: [0, 1, 2, -1, -1, 5]
 
   

 
   

  • print打印所有列表元素
在开头加入:
import numpy as np  
np.set_printoptions(threshold=np.inf)  
  • print (s,file = f)—— print日志到文件
s = '1234'
f = open (r'D:\lianxi\out.txt','w')
print (s,file = f)
f.close()
  • np.diag() —— 创建对角矩阵
1.X=diag(v,k)

以向量v为矩阵X的第k条对角线,当k=0时,向量v为X的主对角线,k>0时,v为主对角线上方的第k条对角线,k<0时,v为主对角线下方的第k条对角线。

格式变体:

X=diag(v):以向量v为矩阵X的主对角线,即默认k=0。

2.v=diag(X,k)

从矩阵中抽取一条对角线返回给向量v。当k=0时,抽取主对角线,k>0时,抽取主对角线上方的第k条对角线,k<0时,抽取主对角线下方的第k条对角线。

格式变体:

V=diag(X):抽取矩阵X的主对角线元素,即默认k=0。

  • Python time clock()方法
该函数有两个功能,

在第一次调用的时候,返回的是程序运行的实际时间;

以第二次之后的调用,返回的是自第一次调用后,到这次调用的时间间隔

在win32系统下,这个函数返回的是真实时间(wall time),而在Unix/Linux下返回的是CPU时间。

所以程序中计时一般用time.time()方法,而不是容易出错的time.clock()
  • print-seq —— 打印分隔符

python print()使用其他分隔符或行终止符打印

可以在 print() 函数中使用 sep 和 end 关键字参数,以你想要的方式输出。比如:

>>print('abc', 'def', '123', sep=',', end='_???\n')
abc,def,123_???
  • numpy.squeeze(a) —— 删除1维度
从数组中删除所有为一的维度;
>>> x = np.array([[[0], [1], [2]]])
>>> x.shape
(1, 3, 1)
>>> np.squeeze(x).shape
(3,)
  • global的单独文件全局性

在python中,全局变量一般有两种使用方式:

第一种:是在一个单独的模块中定义好,然后在需要使用的全局模块中将定义的全局变量模块导入。

第二种:直接在当前的模块中定义好,然后直接在本模块中通过global声明,然后使用.

  • sum(map(sum,a) —— 多维数组元素求和
  • sample —— 随机选取一组元素返回
random.sample(list, 5)
  • choice() —— 随机选取元素
choice() 方法返回一个列表,元组或字符串的随机项。
  • round() —— 四舍五入

round() 是python内置函数,round()不是简单的四舍五入的处理方式。参考文献

>>> round(2.5)
2
>>> round(1.5)
2
>>> round(2.675)
3
>>> round(2.675, 2)
2.67

 round()如果只有一个数作为参数,不指定位数的时候,返回的是一个整数,而且是最靠近的整数(这点上类似四舍五入)。

但是当出现.5的时候,两边的距离都一样,round()取靠近的偶数,这就是为什么round(2.5) = 2。

当指定取舍的小数点位数的时候,一般情况也是使用四舍五入的规则,但是碰到.5的这样情况,如果要取舍的位数前的小树是奇数,则直接舍弃,如果偶数这向上取舍。看下面的示例:

>>> round(2.635, 2)
2.63
>>> round(2.645, 2)
2.65
>>> round(2.655, 2)
2.65
>>> round(2.665, 2)
2.67
>>> round(2.675, 2)
2.67
  • np.linalg.eigvals() —— 求矩阵特征值

# 只求特征值

求特征值加特征向量:

import numpy as np
x= np.mat([[4,-1,-1,-1,-1,0,0,0],[-1,3,-1,0,0,-1,0,0],[-1,-1,3,-1,0,0,0,0],[-1,0,-1,3,0,0,0,-1],[-1,0,0,0,2,0,0,-1],[0,-1,0,0,0,2,-1,0],[0,0,0,0,0,-1,2,-1],[0,0,0,-1,-1,0,-1,3]])
a,b=np.linalg.eig(x)
  • map(op, a, b) —— 用map写点积
import operator
r = range(10000)
sum(map(operator.mul,r,r))

时间最快(参考

import operator
from itertools import izip, starmap
sum(starmap(operator.mul, izip(r,r)))
  • 一句话写乘法口诀表
print ('\n'.join([' '.join(['%s*%s=%-2s' % (y,x,x*y) for y in range(1,x+1)]) for x in range(1,10)]))
  • adjacency_spectrum —— 图的邻接矩阵特征值
# 邻接矩阵的特征值
adjacency_spectrum(G, weight='weight')
    Return eigenvalues of the adjacency matrix of G.
  • nx.all_neighbors —— 图节点的邻居
# 节点的全部邻居
all_neighbors(graph, node)
    Returns all of the neighbors of a node in the graph.
    
    If the graph is directed returns predecessors as well as successors.
  • nx.adjacency_matrix —— 图的邻接矩阵

# 图的邻接矩阵

>>> import scipy as sp
>>> G = nx.Graph([(1,1)])
>>> A = nx.adjacency_matrix(G)
>>> print(A.todense())
    [[1]]
>>> A.setdiag(A.diagonal()*2)
>>> print(A.todense())
    [[2]]
nx.from_numpy_matrix
# 从矩阵画出图
import networkx as nx
import numpy as np
 
A  =  [[0.000000,  0.0000000,  0.0000000,  0.0000000,  0.05119703, 1.3431599],
	   [0.000000,  0.0000000, -0.6088082,  0.4016954,  0.00000000, 0.6132168],
       [0.000000, -0.6088082,  0.0000000,  0.0000000, -0.63295415, 0.0000000],
       [0.000000,  0.4016954,  0.0000000,  0.0000000, -0.29831267, 0.0000000],
       [0.051197,  0.0000000, -0.6329541, -0.2983127,  0.00000000, 0.1562458],
       [1.343159,  0.6132168,  0.0000000,  0.0000000,  0.15624584, 0.0000000]]
 
G = nx.from_numpy_matrix(np.array(A)) 
nx.draw(G, with_labels=True)
  • pattern —— 实现列表元素替换

映射替换,根据一个字典的映射关系替换,下例里把 ‘3’ 和 ‘4’ 都替换成英文:

>>> lst = ['1', '2', '3', '4', '5']
>>> pattern = {'3':'three', '4':'four'}
>>> rep = [pattern[x] if x in pattern else x for x in lst]
>>> rep
['1', '2', 'three', 'four', '5']
  • enumerate —— 取元素列表索引
# 取列表元素索引
for index, value in enumerate(alist):
    if value==0:
        alist[index]=1


猜你喜欢

转载自blog.csdn.net/ztf312/article/details/75313422
今日推荐