栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python CookBook 第三章 数字、日期和时间

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python CookBook 第三章 数字、日期和时间

目录

3.1对数值进行取整和执行精确的小数运算

3.2 对数值进行格式化输出

3.3 同二进制、八进制和十六进制数打交道

3.4 从字节串中打包和解包大整数

3.5复数运算

3.6处理无穷大和NaN

3.7 分数的计算

3.8处理大型数组的计算

3.9随机选择

3.10 时间换算


3.1对数值进行取整和执行精确的小数运算
#简单的取整只需要round函数即可
import math
import pytz
import win32print

nums = [1.234,23.93456,94.9485,937.32566]
nums2 = []
for num in nums:
    nums2.append(round(num,2))
print(nums2)   #[1.23, 23.93, 94.95, 937.33] 当某个数正好为一半是,如1.5,2.5都会取到离得相近偶数上 2
#参数还可以为负数,相应的会取整到十位、百位等上
print(round(13245,-1))  #13240
print(round(12345,-2))  #12300
#在进行格式化操作时,只需要指定浮点数的小数位数就可以
x = 1.4567
print(format(x,'0.2f'))  #1.46
print(format(x,'0.3f'))  #1.457
#但是进行计算时,如果只是普通运算,会出现精度偏差
a = 1.2
b = 2.3
print(a + b == 3.5)
#会在小数点后17位出现一点点的精度偏移,这是因为CPU提供的float运算精度只有17,
#除了在金融领域可能需要更加准确的数据,很难想象在现实世界中难以容忍小数点17的误差(除了拼刀刀),所以不用再在意
#必须精确,那只能运用decimal()函数,会损失一部分性能,这就是在效率与精度之间的抉择了
from decimal import Decimal, localcontext

a = Decimal('1.3')
b = Decimal('1.1')
print(a / b)  #1.181818181818181818181818182
with localcontext() as ltx:
    ltx.prec = 3
    print(a / b)  #1.18
with localcontext() as ltx:
    ltx.prec = 50
    print(a / b)    #1.1818181818181818181818181818181818181818181818182
#当对数据进行处理时,应该明白自己是否能够容忍17位的误差

3.2 对数值进行格式化输出
#在前边我们已经提到对小数的格式化
x = 1123.456789
print(format(x,'0.3f'))  #保留三小数
print(format(x,'>10.3f'))  #向右调整10个字符同时保留三位小数
print(format(x,'<10.3f'))  #向左调整10个字符同时保留三位小数
print(format(x,'^10.3f'))  #居中调整10个字符同时保留三位小数
print(format(x,','))   #千分位分隔符
print(format(x,'0,.1f'))  #千分位分隔符保留一位小数
#使用科学计数法只需要将其f换为e或者E就行
print(format(x,'e'))  #1.123457e+03
print(format(x,'0.2E'))  #1.12E+03
#这些东西也可以直接加载到decimal()函数中

3.3 同二进制、八进制和十六进制数打交道
#将一个整数转换为二进制,八进制和十六进制进行输出
x = 1234
print(bin(x)) #0b10011010010
print(oct(x))  #0o2322
print(hex(x))  #0x4d2
#不想看见 0b 0o 0x这样的前缀,使用format
print(format(x,'b'))  #10011010010
print(format(x,'o'))  #2322
print(format(x,'x'))  #4d2
#将字符串形式的整数转换为不同的进制
print(int('-4d2',16))  #-1234
print(int('-10011010010',2))  #-1234

3.4 从字节串中打包和解包大整数
#这一块内容并不是很常见,在加密技术和网络中有所应用
x = 4121548654687618798465187
print(x.to_bytes(16,'big')) #b'x00x00x00x00x00x03hxc5x99xabYxbaxbdx040xa3'
print(x.to_bytes(16,'little'))  #b'xa30x04xbdxbaYxabx99xc5hx03x00x00x00x00x00'
t = b'xa30x04xbdxbaYxabx99xc5hx03x00x00x00x00x00'
print(int.from_bytes(t,'big'))  #216913489723584705398092437106146148352
print(int.from_bytes(t,'little'))   #4121548654687618798465187

3.5复数运算
#复数通过complex(real,imag)指定,或者直接写加上j
a = complex(1,2)
b = 2 - 3j
print(a,b)  #(1+2j) (2-3j)
print(a.real,a.imag) # 1.0 2.0 提取实部和虚部
#运算
print(a + b)  #(3-1j)
print(a*b)  #(8+1j)
print(a / b)  #(-0.30769230769230776+0.5384615384615384j)
#和数学相关的模块大部分复数都适用
import numpy as np
a = np.array([1+2j,4+6j,3+9j,7-8j])
print(a)  #[1.+2.j 4.+6.j 3.+9.j 7.-8.j]
print(a+2)#[3.+2.j 6.+6.j 5.+9.j 9.-8.j]
print(np.sin(a))  #[   3.16577851+1.95960104e+00j -152.65889676-1.31848519e+02j 571.75364329-4.01099608e+03j  979.22483461-1.12367535e+03j]
#必须使用cmath 才可以产生数学上的复数
import cmath
a = cmath.sqrt(-1)
print(a)   #1j

3.6处理无穷大和NaN
#使用isinf()和isnan()进行判断
a = float('inf')
b = float('nan')
print(math.isinf(a))  #Ture
print(a)   #inf
print(a + 10)   #inf  无穷大会进行传播
#无穷大对未定义的行为产生NaN
c = a/a
print(c) #nan
#NaN会对所有行为产生传播,不会异常
d = float('nan')
print(d -23)  #nan
print( d + 8)  #nan
print(math.isnan(d))  #True

3.7 分数的计算
# fractions模块
from fractions import Fraction
a = Fraction(3,4)
b = Fraction(1,2)
print(a+b)  #5/4
print(a-b)  #1/4
print(a*b)  #3/8
#转化为小数
print(float(a)) #0.75
c = 0.125
#将小数转化为分数fractins
d = Fraction(*c.as_integer_ratio())
print(d)  #1/8

3.8处理大型数组的计算
# 使用Numpy进行大型的数据集计算
import numpy as py
ax = np.array([1,2,34,5,6,7,8,3])
ay = np.array([2,34,5,3,6,34,233,3])
print(ax + 2)  #[ 3  4 36  7  8  9 10  5]
print(ax * ay)  #[   2   68  170   15   36  238 1864    9]
# 计算多项式
print(ax*3-9 - ay/2+10)  #[  3.  -10.  100.5  14.5  16.    5.  -91.5   8.5]
#创建一个大型数集
# grid = np.zeros(shape=(10000,10000),dtype=float)
# print(grid)
'''
[[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.]]'''
# print(grid+10)
'''
[[10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]
 ...
 [10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]]'''
# print(np.sin(grid+10))
'''
[[-0.54402111 -0.54402111 -0.54402111 ... -0.54402111 -0.54402111
  -0.54402111]
 [-0.54402111 -0.54402111 -0.54402111 ... -0.54402111 -0.54402111
  -0.54402111]
 [-0.54402111 -0.54402111 -0.54402111 ... -0.54402111 -0.54402111
  -0.54402111]
 ...
 [-0.54402111 -0.54402111 -0.54402111 ... -0.54402111 -0.54402111
  -0.54402111]
 [-0.54402111 -0.54402111 -0.54402111 ... -0.54402111 -0.54402111
  -0.54402111]
 [-0.54402111 -0.54402111 -0.54402111 ... -0.54402111 -0.54402111
  -0.54402111]]'''
#数组的常规操作
a = np.array([[1,2,3,4],[4,5,6,7],[7,8,9,10],[12,23,45,52]])
print(a)
# [[ 1  2  3  4]
#  [ 4  5  6  7]
#  [ 7  8  9 10]
#  [12 23 45 52]]
#寻找第一行
print(a[1])  #[4 5 6 7]
#寻找第二列
print(a[:,1])  #[ 2  5  8 23]
#改变值  改变行数1,2列数1,2 位子的值
a [1:3,1:3] += 10
print(a)
# [[ 1  2  3  4]
#  [ 4 15 16  7]
#  [ 7 18 19 10]
#  [12 23 45 52]]
#全部增加
print(a+100)
# [[101 102 103 104]
#  [104 115 116 107]
#  [107 118 119 110]
#  [112 123 145 152]]
print(np.where(a<10,a,10))
# [[ 1  2  3  4]
#  [ 4 10 10  7]
#  [ 7 10 10 10]
#  [10 10 10 10]]

3.9随机选择
import random
values = [1,2,3,4,5]
# 从序列中随机挑选出一个元素
a = random.choice(values)
print(a)
# 抽出N个元素
b = random.sample(values,2)
print(b)
c = random.sample(values,3)
print(c)
#随机打乱顺序
random.shuffle(values)
print(values)
#产生随机数
print(random.randint(0,10))
print(random.randint(0,10))
#产生浮点数
print(random.random())
print(random.random())
#产生N个随机比特位所表示的整数
print(random.getrandbits(50))
print(random.getrandbits(50))
#random模块含有特定的算法,但是可以通过random.seed()修改种子值
random.seed()  #参照系统时间
random.seed(12345)  #参照给定的数值
random.seed(b'bytedata')  #参照字节数据
#其他分布式
# 均匀分布
random.uniform(1,10)
#正态分布
random.gauss(2,4)

3.10 时间换算
# 使用datatime实例和标准数学运算
from datetime import timedelta,datetime
a = datetime(2022,4,2)
print(a + timedelta(days=10))  #2022-04-12 00:00:00
b = datetime.now()
print(b)    #2022-05-02 09:38:11.783966
print(b - a)  #30 days, 9:38:39.925799
print(b + timedelta(minutes=10))  #2022-05-02 09:49:50.610530  #,但是对月份不太灵,会报错
#闰年同样可以识别
a = datetime(2012,2,28)
b = datetime(2012,3,1)
print(b - a)   #2 days, 0:00:00
c = datetime(2013,2,28)
d = datetime(2013,3,1)
print(d - c)#2 days, 0:00:00
# dateutil.relativedelta()函数可以处理不同月份的天数,
from dateutil.relativedelta import relativedelta
a = datetime(2012,9,23)
print(a + relativedelta(months=+1))  #2012-10-23 00:00:00
print(a + relativedelta(months=+4))#2013-01-23 00:00:00
b = datetime(2012,2,21)
print(a - b) #215 days, 0:00:00
print(relativedelta(a,b))   #relativedelta(months=+7, days=+2)
#找出每个周1的日期
from datetime import datetime
from dateutil.relativedelta import relativedelta
from dateutil.rrule import *

d = datetime.now()
print(d)  #2022-05-02 10:00:40.983401  周一
q = d + relativedelta(weekday=MO)  #2022-05-02 10:09:22.607117  第一个周一
print(q)
p = d + relativedelta(weekday=MO(2))  #2022-05-09 10:09:22.607117  第二个周一  周一-周日为MO,TU,WE,TH,FR,SA,SU
print(p)
#使用datetime.timedelta对日期进行迭代
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)  #快速得出这个月的1日
        _,days_in_month = calendar.monthrange(year=start_date.year,month=start_date.month)  #计算这个一共多少天 如果没有_,就会返回一个元组(),第一个0~6代表周一至周日,第二个为天数28~31
        print(days_in_month)
        end_data = start_date + timedelta(days=days_in_month)  #得出下个月1日日期
        return (start_date,end_data)

a_day = timedelta(days=1)
frist_day,last_day = get_month_range()
while frist_day < last_day:
    print(frist_day)
    frist_day += a_day
'''
2022-05-01
2022-05-02
2022-05-03
2022-05-04
...
'''
#还有一种办法是生成一个生成器
def data_range(start,stop,step):
    while start < stop:
        yield start
        start += step

for d in data_range(datetime(2022,5,1),datetime(2022,6,1),timedelta(days=1)):
    print(d)
'''
2022-05-01 00:00:00
2022-05-02 00:00:00
2022-05-03 00:00:00
2022-05-04 00:00:00
2022-05-05 00:00:00
...
'''
#将字符串转化为日期
from datetime import datetime
text = '2022-05-01'
y = datetime.strptime(text,'%Y-%m-%d')
print(y)
z = datetime.now()  #2022-05-01 00:00:00
nice_z = datetime.strftime(z,'%A %B %d,%Y')
print(nice_z)  #Monday May 02,2022
#如果知道整体的的时间格式,使用split()函数进行分割,重新datetime(),效率会提高很多

#处理涉及到时区的时间问题
from datetime import datetime
from pytz import timezone
d = datetime(2022,5,2,11,30,0)
print(d)
China = pytz.country_timezones['CN']
print(China)  #使用ISO 3166国家代码找到时区名称
cen = timezone('Asia/Shanghai')
loca_d = cen.localize(d)
print(loca_d)   #2022-05-02 11:30:00+08:00
#转化为美国时间
us_d = loca_d.astimezone(timezone('US/Central'))
print(us_d) #2022-05-01 22:30:00-05:00
#处理本地时间时最好是先转化为世界统一时间UTC
utc_d = loca_d.astimezone(pytz.utc)
print(utc_d)  #2022-05-02 03:30:00+00:00
later_t = utc_d + timedelta(minutes=30)
print(later_t.astimezone(cen)) #2022-05-02 12:00:00+08:00

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/849889.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号