python3数字、日期和时间
1、对数值进行取整
#使用内建的round(value,ndigits)函数来取整,ndigits指定保留的位数,在取整时会取值在偶数上,如1.25取一位会取整1.2,1.26会取整1.3 In [1]: round(1.23,1) Out[1]: 1.2 In [2]: round(1.25,1) Out[2]: 1.2 In [3]: round(1.26,1) Out[3]: 1.3 In [4]: round(1.2645,3) Out[4]: 1.264 #如果参数ndigits为负数的话会相应的取整到十位、白位和千位 In [1]: a = 1234567 In [2]: round(a,-1) Out[2]: 1234570 In [3]: round(a,-3) Out[3]: 1235000 #通过格式化操作取小数精度 In [4]: x = 1.23456 In [5]: format(x,'0.2f') Out[5]: '1.23' In [6]: 'value is {:0.3f}'.format(x) Out[6]: 'value is 1.235'
2、执行精确的小数计算
#在数学计算中由于CPU的浮点运算单元特性导致会引入微小的误差 In [11]: a = 4.2 In [12]: b = 2.1 In [13]: a + b Out[13]: 6.300000000000001 In [14]: (a + b) == 6.3 Out[14]: False #可以通过Decimal模块来将数字以字符串的形式来指定,但它支持所有常见的数学操作 In [27]: from decimal import Decimal In [28]: a = Decimal('4.2') In [29]: b = Decimal('2.1') In [30]: a + b Out[30]: Decimal('6.3') In [31]: print(a + b) 6.3 In [32]: print(type(a + b)) <class 'decimal.Decimal'> In [33]: (a + b) == Decimal('6.3') Out[33]: True #decimal模块的主要功能是允许控制计算过程中的各个方面,包括数字位数的四舍五入,可以通过创建本地的上下文环境来修改其设定 In [34]: from decimal import localcontext In [35]: a = Decimal('1.3') In [36]: b = Decimal('1.7') In [37]: a / b Out[37]: Decimal('0.7647058823529411764705882353') In [38]: with localcontext() as ctx: ...: ctx.prec = 3 #指定精确位数 ...: print(a / b) ...: 0.765 In [39]: with localcontext() as ctx: ...: ctx.prec = 30 ...: print(a / b) ...: 0.764705882352941176470588235294 #如果在数字进行运算时可以使用math.fsum()精确误差 In [41]: nums = [1.23,10,1,-10,-1.23] In [42]: sum(nums) Out[42]: 1.0000000000000004 In [44]: import math In [46]: math.fsum(nums) Out[46]: 1.0
3、对数值做格式化输出
In [47]: x = 1234.56789 #格式化时精确2位小数 In [48]: format(x,'0.2f') Out[48]: '1234.57' #右对齐宽度20精确小数3位格式化 In [49]: 'value is{:>20.3f}'.format(x) Out[49]: 'value is 1234.568' #左对齐宽度20精确小数位3位格式化 In [50]: 'value is{:<20.3f}'.format(x) Out[50]: 'value is1234.568 ' #剧中对齐20宽度精确3位小数位格式化 In [51]: 'value is{:^20.3f}'.format(x) Out[51]: 'value is 1234.568 ' #指定逗号为千位分隔符 In [52]: 'value is{:^20,.1f}'.format(x) Out[52]: 'value is 1,234.6 ' #使用科学计算法输出 In [53]: 'value is{:^20,.4e}'.format(x) Out[53]: 'value is 1.2346e+03 ' In [54]: 'value is{:^20,.4E}'.format(x) Out[54]: 'value is 1.2346E+03 '
4、同二进制、八进制和十六进制数打交道
In [55]: num = 12345 #转换为二进制 In [56]: bin(num) Out[56]: '0b11000000111001' #转换为八进制 In [57]: oct(num) Out[57]: '0o30071' #转换为十六进制 In [58]: hex(num) Out[58]: '0x3039' #通过format()函数也可以转换,它会省去前面的标识0b\0o\0x In [59]: format(num,'b') Out[59]: '11000000111001' In [60]: format(num,'o') Out[60]: '30071' In [61]: format(num,'x') Out[61]: '3039' #处理负数 In [62]: x = -1234 In [63]: format(x,'b') Out[63]: '-10011010010' In [64]: format(x,'o') Out[64]: '-2322' In [65]: format(x,'x') Out[65]: '-4d2' #通过字符串回转只需要通过int函数转换为数字并指定进制即可 In [66]: int('-4d2',16) Out[66]: -1234 In [67]: int('-2322',8) Out[67]: -1234 In [68]: int('-10011010010',2) Out[68]: -1234 #在python中指定八进制的语法是在添加前缀0o,如修改文件权限时,不加上前缀将会报错 In [1]: import os In [2]: os.chmod('test.py',0777) File "<ipython-input-2-ddababe9874c>", line 1 os.chmod('test.py',0777) ^ SyntaxError: invalid token #指定数据为八进制 In [3]: os.chmod('test.py',0o0777)
5、从字节串中打包和解包大整数
In [4]: x = 23**23 In [5]: x Out[5]: 20880467999847912034355032910567 #将大整数转换为字节串,使用int.to_bytes()方法,指定字节数和字节序即可 In [8]: x.to_bytes(16,'big') Out[8]: b'\x00\x00\x01\x07\x8cnO}uE\x0b\x1f\xb3\xecj\xe7' #将字节转换为整数,使用int.from_bytes()方法,指定字节序即可 In [9]: data = b'\x00\x00\x01\x07\x8cnO}uE\x0b\x1f\xb3\xecj\xe7' In [10]: len(data) Out[10]: 16 In [11]: int.from_bytes(data,'big') Out[11]: 20880467999847912034355032910567 #指定从小到大的字节序 In [12]: int.from_bytes(data,'little') Out[12]: 307606851333435471716003534337847918592 #如果指定的字节数位数不够将会报错,可以使用int.bit_length()方法来确定需要多少位的值才能保存这个值 In [13]: xx = 523 ** 23 In [14]: xx Out[14]: 335381300113661875107536852714019056160355655333978849017944067 In [15]: xx.to_bytes(16,'little') --------------------------------------------------------------------------- OverflowError Traceback (most recent call last) <ipython-input-15-2f3e88637b10> in <module>() ----> 1 xx.to_bytes(16,'little') OverflowError: int too big to convert In [17]: xx.bit_length() Out[17]: 208 In [18]: x.to_bytes(208,'little') Out[18]: b'\xe7j\xec\xb3\x1f\x0bEu}On\x8c\x07\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00...'
6、复数运算
#创建复数 In [19]: a = complex(2,4) In [20]: b = 3 - 5j In [22]: a,b Out[22]: ((2+4j), (3-5j)) #取实属部分 In [23]: a.real Out[23]: 2.0 #取虚数部分 In [24]: a.imag Out[24]: 4.0 #取共取值 In [25]: a.conjugate() Out[25]: (2-4j) #复数运算操作 In [26]: a + b Out[26]: (5-1j) In [27]: a - b Out[27]: (-1+9j) In [28]: a * b Out[28]: (26+2j) In [29]: a / b Out[29]: (-0.4117647058823529+0.6470588235294118j) In [30]: abs(a) Out[30]: 4.47213595499958 #复数的函数操作正弦、余弦和平方根,可以使用cmath模块 In [31]: import cmath #正弦 In [32]: cmath.sin(a) Out[32]: (24.83130584894638-11.356612711218173j) #余弦 In [33]: cmath.cos(a) Out[33]: (-11.36423470640106-24.814651485634183j) #平方根 In [34]: cmath.exp(a) Out[34]: (-4.829809383269385-5.5920560936409816j) #使用numpy模块直接创建复数数组,并对他们执行操作 In [1]: import numpy as np In [2]: a = np.array([2+3j,4+5j,6-7j,8+9j]) In [3]: a Out[3]: array([2.+3.j, 4.+5.j, 6.-7.j, 8.+9.j]) In [4]: a + 2 Out[4]: array([ 4.+3.j, 6.+5.j, 8.-7.j, 10.+9.j]) In [5]: np.sin(a) Out[5]: array([ 9.15449915 -4.16890696j, -56.16227422 -48.50245524j, -153.20827755-526.47684926j, 4008.42651446-589.49948373j])
7、处理无穷大和NaN
#无穷大、负无穷大和NaN可以通过float()函数来创建 In [6]: a = float('inf') In [7]: b = float('-inf') In [8]: c = float('nan') In [9]: a,b,c Out[9]: (inf, -inf, nan) #通过math.isinf()和math.isnan()函数来检测是否出现这些值 In [11]: import math In [12]: math.isinf(a) Out[12]: True In [13]: math.isnan(c) Out[13]: True In [14]: math.isinf(b) Out[14]: True #无穷大在数学计算中应用 In [15]: a + 100 Out[15]: inf In [16]: a * 100000 Out[16]: inf In [17]: 10 / a Out[17]: 0.0 #特定的操作会产生NaN结果 In [18]: a/a Out[18]: nan In [19]: a + b Out[19]: nan In [20]: c + 2345 Out[20]: nan In [21]: c / 2222222 Out[21]: nan In [23]: c * 33323333333 Out[23]: nan In [24]: math.sqrt(c) Out[24]: nan #NaN在做比较时从不会判定为相等 In [25]: x = float('nan') In [26]: y = float('nan') In [27]: x == y Out[27]: False In [28]: x is y Out[28]: False #唯一能检测是否为NaN的办法只有math.isnan()方法 In [29]: math.isnan(x) Out[29]: True
8、分数的计算
#fractions模块可以用来处理涉及分数的数学计算 In [1]: from fractions import Fraction In [2]: a = Fraction(3,4) In [3]: b = Fraction(4,8) In [4]: print(a+b) 5/4 In [5]: print(a-b) 1/4 In [6]: print(a*b) 3/8 In [7]: c = a * b In [8]: c Out[8]: Fraction(3, 8) #显示分数 In [9]: c.numerator Out[9]: 3 #显示母数 In [10]: c.denominator Out[10]: 8 #将分数转换为浮点数 In [11]: float(c) Out[11]: 0.375 #限制分母 In [12]: print(c.limit_denominator(4)) 1/3 #将浮点数转换为分数 In [13]: x = 3.75 In [14]: y = Fraction(*x.as_integer_ratio()) In [15]: y Out[15]: Fraction(15, 4) In [16]: print(y) 15/4
9、处理大型数组的计算
#大型数组的计算可以使用numpy库来运算 In [17]: import numpy as np In [18]: ax = np.array([1,2,3,4]) In [19]: ay = np.array([5,6,7,8]) In [20]: ax * 3 Out[20]: array([ 3, 6, 9, 12]) In [21]: ax / 2 Out[21]: array([0.5, 1. , 1.5, 2. ]) In [22]: ax - ay Out[22]: array([-4, -4, -4, -4]) In [23]: ax + ay Out[23]: array([ 6, 8, 10, 12]) In [24]: ax * ay Out[24]: array([ 5, 12, 21, 32]) #多计算组合 In [25]: def f(x): ...: return 2 * x + 10 ...: ...: In [26]: f(ax) Out[26]: array([12, 14, 16, 18]) In [27]: f(ay) Out[27]: array([20, 22, 24, 26]) #计算数组的平方根 In [28]: np.sqrt(ax) Out[28]: array([1. , 1.41421356, 1.73205081, 2. ]) #余弦数 In [29]: np.cos(ax) Out[29]: array([ 0.54030231, -0.41614684, -0.9899925 , -0.65364362]) #正弦数 In [30]: np.sin(ax) Out[30]: array([ 0.84147098, 0.90929743, 0.14112001, -0.7568025 ]) #通过numpy创建二维浮点数组 In [31]: grid = np.zeros(shape=(1000,1000),dtype=float) In [32]: grid Out[32]: array([[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.]]) #数组计算 In [33]: grid += 11 In [34]: grid Out[34]: array([[11., 11., 11., ..., 11., 11., 11.], [11., 11., 11., ..., 11., 11., 11.], [11., 11., 11., ..., 11., 11., 11.], ..., [11., 11., 11., ..., 11., 11., 11.], [11., 11., 11., ..., 11., 11., 11.], [11., 11., 11., ..., 11., 11., 11.]]) #数组正弦 In [35]: np.sin(grid) Out[35]: array([[-0.99999021, -0.99999021, -0.99999021, ..., -0.99999021, -0.99999021, -0.99999021], [-0.99999021, -0.99999021, -0.99999021, ..., -0.99999021, -0.99999021, -0.99999021], [-0.99999021, -0.99999021, -0.99999021, ..., -0.99999021, -0.99999021, -0.99999021], ..., [-0.99999021, -0.99999021, -0.99999021, ..., -0.99999021, -0.99999021, -0.99999021], [-0.99999021, -0.99999021, -0.99999021, ..., -0.99999021, -0.99999021, -0.99999021], [-0.99999021, -0.99999021, -0.99999021, ..., -0.99999021, -0.99999021, -0.99999021]]) #numpy扩展了python列表的索引功能 In [36]: a = np.array([[1,2,3],[4,5,6],[7,8,9]]) In [37]: a Out[37]: array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) #索引第一层 In [38]: a[1] Out[38]: array([4, 5, 6]) In [39]: a[0] Out[39]: array([1, 2, 3]) In [40]: a[:] Out[40]: array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 索引第二层 In [41]: a[:,1] Out[41]: array([2, 5, 8]) In [42]: a[1:3,1:3] Out[42]: array([[5, 6], [8, 9]]) In [43]: a[0:3,0:3] Out[43]: array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) In [44]: a[0:3,1:3] Out[44]: array([[2, 3], [5, 6], [8, 9]]) #对索引进行运算操作 In [45]: a[0:3,1:3] += 10 In [46]: a Out[46]: array([[ 1, 12, 13], [ 4, 15, 16], [ 7, 18, 19]]) In [47]: a + 10 Out[47]: array([[11, 22, 23], [14, 25, 26], [17, 28, 29]]) In [48]: a Out[48]: array([[ 1, 12, 13], [ 4, 15, 16], [ 7, 18, 19]]) #对数组中小于10以外的值运算加10 In [49]: np.where(a < 10 ,a ,a+10) Out[49]: array([[ 1, 22, 23], [ 4, 25, 26], [ 7, 28, 29]]) #numpy是使用最为庞大和复杂的模块之一,官方站点:http://www.numpy.org
10、矩阵和线性代数的计算
#numpy库中的matrix对象可以用来处理线性代数 In [50]: import numpy as np In [51]: m = np.matrix([[1,2,3],[4,5,6],[7,8,9]]) In [52]: m Out[52]: matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) In [53]: m.T Out[53]: matrix([[1, 4, 7], [2, 5, 8], [3, 6, 9]]) In [55]: v = np.matrix([[22],[33],[44]]) In [56]: v Out[56]: matrix([[22], [33], [44]]) In [57]: m * v Out[57]: matrix([[220], [517], [814]]) In [58]: from numpy import linalg In [59]: linalg.det(m) Out[59]: 0.0 In [60]: linalg.eigvals(m) Out[60]: array([ 1.61168440e+01, -1.11684397e+00, -1.30367773e-15])
11、随机选择
#random模块中的choice()提供随机选择元素 In [62]: import random In [63]: values = [1,2,3,4,5,6,7,8,9] In [64]: random.choice(values) Out[64]: 4 In [65]: random.choice(values) Out[65]: 2 In [66]: random.choice(values) Out[66]: 6 #随机选出多个元素可以使用random.samle() In [68]: random.sample(values,2) Out[68]: [4, 8] In [69]: random.sample(values,3) Out[69]: [3, 8, 9] In [70]: random.sample(values,5) Out[70]: [1, 7, 4, 3, 5] #原地打乱元素顺序可以使用random.shuffle() In [71]: values Out[71]: [1, 2, 3, 4, 5, 6, 7, 8, 9] In [72]: random.shuffle(values) In [73]: values Out[73]: [8, 7, 2, 5, 9, 3, 1, 6, 4] #生成随机数可以使用random.randint() In [74]: random.randint(1,1000) Out[74]: 534 In [75]: random.randint(1,1000) Out[75]: 675 In [76]: random.randint(1,1000) Out[76]: 969 #产生0到1之间的浮点随机数可以使用random.random() In [77]: random.random() Out[77]: 0.4467371549631729 In [78]: random.random() Out[78]: 0.870836619476411 In [79]: random.random() Out[79]: 0.7285090986539235 #如果要得到由N个随机比特位表示的整数,可以使用random.getrandbits() In [81]: random.getrandbits(50) Out[81]: 898644577661596 In [82]: random.getrandbits(50) Out[82]: 825711475826498 In [83]: random.getrandbits(50) Out[83]: 877330983329038
12、时间换算
#利用datetime模块来完成不同时间单位间的换算,timedelta实例完成时间间隔换算 In [103]: from datetime import datetime,timedelta #当前时间加2天后的时间 In [104]: datetime.now() + timedelta(days=2) Out[104]: datetime.datetime(2018, 11, 17, 14, 0, 16, 257925) #当前时间加5小时后的时间 In [105]: datetime.now() + timedelta(hours=5) Out[105]: datetime.datetime(2018, 11, 15, 19, 0, 49, 178027) #当前时间加30秒后的时间 In [106]: datetime.now() + timedelta(seconds=30) Out[106]: datetime.datetime(2018, 11, 15, 14, 2, 26, 290114) #创建一个小时实例 In [109]: x = timedelta(hours=2) #创建一个60秒的时间实例 In [110]: y = timedelta(seconds=60) In [111]: c = x + y In [112]: c.days Out[112]: 0 #换算成秒 In [113]: c Out[113]: datetime.timedelta(seconds=7260) #换算成时间 In [114]: c.seconds / 3600 Out[114]: 2.0166666666666666 In [117]: c.total_seconds() Out[117]: 7260.0 In [118]: c.total_seconds() / 3600 Out[118]: 2.0166666666666666 #创建时间实例 In [119]: a = datetime(2018,10,10) #输出10天后的时间 In [120]: print(a + timedelta(days=10)) 2018-10-20 00:00:00 #创建时间实例 In [121]: b = datetime(2017,5,8) In [122]: d = a - b #两个时间的时间差 In [123]: d Out[123]: datetime.timedelta(days=520) In [124]: d.days Out[124]: 520 #时间差的秒数 In [125]: d.total_seconds() Out[125]: 44928000.0
13、计算上周5的日期
from datetime import datetime,timedelta weekdays = ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'] def get_previous_byday(dayname,start_date=None): if start_date is None: start_date = datetime.today() #获取当前时间 day_num = start_date.weekday() #获取时间的星期 day_num_target = weekdays.index(dayname) #获取查询星期 days_ago = (7 + day_num - day_num_target) % 7 #获取日期差的天数 if days_ago == 0: days_ago = 7 target_date = start_date - timedelta(days=days_ago) #计算时间差 return target_date print('现在时间:',datetime.today()) print(get_previous_byday('Monday')) print(get_previous_byday('Tuesday',datetime(2018,10,23))) print(get_previous_byday('Saturday',datetime(2018,8,8))) print(get_previous_byday('Friday')) # 现在时间: 2018-11-15 15:41:03.775963 2018-11-12 15:41:03.775963 2018-10-16 00:00:00 2018-08-04 00:00:00 2018-11-09 15:41:03.775963
14、找出当月的日期范围
from datetime import datetime,date,timedelta import calendar def get_month_range(start_date=None): if start_date is None: start_date = date.today().replace(day=1) else: start_date = start_date.replace(day=1) #替换输入时间的日期为1得到开始时间 _,days_in_month = calendar.monthrange(start_date.year,start_date.month) #calendar.monthrange()函数返回当月的第一个工作日和当月的天数 end_date = start_date + timedelta(days=days_in_month) #起始时间加当月天数获得截至时间 a_day = timedelta(days=1) #定义一天时间对象 while start_date < end_date: print(start_date) start_date += a_day get_month_range() get_month_range(date(2018,10,23)) # 2018-10-01 2018-10-02 2018-10-03 2018-10-04 2018-10-05 2018-10-06 2018-10-07 2018-10-08 ......
from datetime import datetime,timedelta def date_range(start,stop,step): while start < stop: yield start start += step for i in date_range(datetime(2018,10,15),datetime(2018,11,10),timedelta(hours=24)): print(i) # 2018-10-15 00:00:00 2018-10-16 00:00:00 2018-10-17 00:00:00 2018-10-18 00:00:00 2018-10-19 00:00:00 2018-10-20 00:00:00 2018-10-21 00:00:00 2018-10-22 00:00:00 ......
15、将字符串转换为日期
In [10]: from datetime import datetime In [11]: date = '2018-11-16' #将字符串转换为日期 In [12]: datetime.strptime(date,'%Y-%m-%d') Out[12]: datetime.datetime(2018, 11, 16, 0, 0) #获取当前日期 In [13]: datetime.now() Out[13]: datetime.datetime(2018, 11, 16, 10, 56, 7, 487189) In [14]: z = datetime.now() #将日期格式化为阅读的日期形式 In [15]: datetime.strftime(z,'%A %B %d, %Y') Out[15]: 'Friday November 16, 2018' #使用自编写函数来处理字符串转日期要比datetime.strptime()快很多 In [16]: def parse_ymd(s): ...: year_s,mon_s,day_s = s.split('-') ...: return datetime(int(year_s),int(mon_s),int(day_s)) ...: ...: In [17]: parse_ymd('2018-11-16') Out[17]: datetime.datetime(2018, 11, 16, 0, 0)
16、处理涉及到时区的日期问题
In [24]: from datetime import datetime,time,date In [25]: import pytz #查看中国时区 In [26]: pytz.country_timezones('cn') Out[26]: ['Asia/Shanghai', 'Asia/Urumqi'] #创建中国时区对象 In [28]: tz = pytz.timezone('Asia/Shanghai') #创建时间对象时指定时区 In [29]: datetime.now(tz) Out[29]: datetime.datetime(2018, 11, 16, 13, 32, 59, 744669, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>) #指定时区创建日期对象 In [30]: datetime(2018,11,16,tzinfo=tz) Out[30]: datetime.datetime(2018, 11, 16, 0, 0, tzinfo=<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>) #指定时区创建时间对象 In [31]: time(13,33,00,tzinfo=tz) Out[31]: datetime.time(13, 33, tzinfo=<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>) #本地化时间对象 In [33]: tz.localize(datetime.now()) Out[33]: datetime.datetime(2018, 11, 16, 13, 41, 28, 395602, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>) #创建本地化时间对象 In [34]: loc_d = tz.localize(datetime.now()) #通过本地化时间对象转化为其他时区时间 In [35]: loc_d.astimezone(pytz.timezone('America/New_York')) Out[35]: datetime.datetime(2018, 11, 16, 0, 42, 43, 666067, tzinfo=<DstTzInfo 'America/New_York' EST-1 day, 19:00:00 STD>) #转换为UTC时间对象 In [36]: loc_d.astimezone(pytz.utc) Out[36]: datetime.datetime(2018, 11, 16, 5, 42, 43, 666067, tzinfo=<UTC>) In [37]: loc_d Out[37]: datetime.datetime(2018, 11, 16, 13, 42, 43, 666067, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>) In [38]: utc_d = loc_d.astimezone(pytz.utc) In [39]: print(utc_d) 2018-11-16 05:42:43.666067+00:00 #将UTC时间转换为合适的时区 In [40]: later_utc = utc_d + timedelta(minutes=30) In [41]: print(later_utc.astimezone(tz)) 2018-11-16 14:12:43.666067+08:00