python 食谱-day05

3、数字日期和时间

3.1数字的四舍五入
print(round(1.23,1))
print(round(1.27,1))
print(round(1.5,0))
print(round(2.5,0))#当一个值刚好在两个边界的中间的时候,`round()`函数返回离它最近的偶数。
print(round(3.5,0))

1.2
1.3
2.0
2.0
4.0

  传给round()函数的ndigits参数可以是附属,这种情况下,舍入运算会作用在十位、百位、千位等上面。

数字的格式化(是小数点后保留几位小数),注意区分与四舍五入之间的差别

print(format( 1.23,'0.1f'))
print(format( 1.27,'0.1f'))
print(format( 1.5,'0.0f'))
print(format( 2.5,'0.0f'))
print(format( 3.5,'0.0f'))

1.2
1.3
2
2
4

3.2执行精确的浮点数运算

浮点数的一个普遍问题是它们并不能精确的表示十进制数。并且,即使是最简单的数学运算也会产生小的误差。

a = 4.2
b = 2.1
print(a+b)#6.300000000000001

这些错误是由底层CPU和IEEE754标准通过自己的浮点单位去执行算术时的特征,由于Python的浮点数据类型使用底层表示数据存储,因此你没办法避免这样的误差。

from decimal import Decimal
a = Decimal('4.2')
b = Decimal('2.1')
print(type(a+b))#<class 'decimal.Decimal'>
print(a+b)#6.3

decimal模块的一个主要特征是允许你控制计算的每一方面,包括数字位数和四舍五入运算。为了这么做,你先得创建一个本地上下文并更改它的位置。

from decimal import Decimal,localcontext
a = Decimal('1.3')
b = Decimal('1.7')
print(a/b)#0.7647058823529411764705882353

with localcontext() as ctx:
    ctx.prec = 3
    print(a/b)#0.765

with localcontext() as ctx:
    ctx.prec = 50
    print(a/b)#0.76470588235294117647058823529411764705882352941176
nums = [1.23e+18,1,-1.23e+18]
print(sum(nuts))#0.0
nums = [1.23e+18,-1.23e+18,1]
print(sum(nuts))#1.0

这个错误可以利用math.fsum()所提供的更精确的计算能力来解决

import math
nums = [1.23e+18,1,-1.23e+18]
print(math.fsum(nuts))#1.0
nums = [1.23e+18,-1.23e+18,1]
print(math.fsum(nuts))#1.0

总的来说,decimal模块主要用在涉及到金融的领域。

3.3数字的格式化输出

  你需要将数字格式化后输出,并控制数字的位数、对齐、千位分隔符和其他的细节。
  格式化输出单个数字的时候,可以使用内置的 format()函数

format()

  如果你想使用指数记法,将f改成e或者E(取决于指数输出的大小写形式)

x = 1234.56789
print(format(x,'e'))#1.234568e+03
print(format(x,'0.2E'))#1.23E+03

  在很多Python代码中会看到使用%来格式化数字的

使用%来格式化数字
3.4二八十六进制整数

  你需要转换或者输出使用二进制,八进制或十六进制表示的整数。
  为了将整数转换为二进制、八进制、或十六进制的文本串,可以分别使用bin()oct(),或hex()函数:
   如果不想输出0b,0o,0x的前缀的话,可以使用format()函数

x = 32
print(bin(x))#0b100000
print(format(x,'b'))#100000  
print(oct(x))#0o40
print(format(x,'o'))#40
print(hex(x))#0x20
print(format(x,'x'))#20

为了将不同进制的数转换为整数,简单的使用带有进制的int()函数即可

print(int('20',16))#32
print(int('11111',2))#31
3.5字节到大整数的打包与解包

  你有一个字节字符串并想将它解压成一个整数。或者,你需要将一个大整数转换为一个字节字符串。
  假设你的程序需要处理一个拥有128位长的16个元素的字节字符串。

3.6复数的数学运算
3.8分数运算

fractions模块可以被用来执行包含分数的数学运算

from fractions import  Fraction
a = Fraction(5,4)
b = Fraction(3,4)
print(a)#5/4
print(a+b)#2
c = a * b
print(c)#15/16
print(c.numerator)#分子 15
print(c.denominator)#分母 16
print(float(c))#0.9375 将分数转换为小数
print(c.limit_denominator(7))#这个是什么意思

print(Fraction(*3.75.as_integer_ratio()))#将小数转换为分数  15/4

直接使用分数可以减少手动转换为小数或浮点数的工作。

3.9大型数组运算

涉及到数组的重量级运算操作,可以使用Numpy库,Numpy的一个主要特征是它会给Python提供一个数组对象,相比标准的Python列表更适合用来做数学运算,

#普通的py数组
x = [1,2,3,4]
y = [5,6,7,8]
print(x*2) #并不是对应元素的值乘以2,而是整体输出打印两次 [1, 2, 3, 4, 1, 2, 3, 4]
print(x+y) #并不是对应元素的和,而是列表的合并[1, 2, 3, 4, 5, 6, 7, 8]
# print(x * y)注意,这个会报错  TypeError: can't multiply sequence by non-int of type 'list'
#Numpy中的数组
import  numpy as np
ax = np.array([1,2,3,4])
ay = np.array([5,6,7,8])
print(ax*2)#[2 4 6 8]
print(ax+ay)#[ 6  8 10 12]
print(ax*ay)#[ 5 12 21 32]

  Numpy中的标量运算(比如ax * 2ax+10)会作用在每一个元素上。另外,当两个操作数都是数组的时候执行元素对等位置计算,并最终生成一个新的数组。
  对整个数组中的所有元素同时执行数学运算可以使得作用在整个数组上的函数运算简单而又快速。

对整个数组中所有元素同时执行数学运算可以使得作用在整个数组上的函数运算简单而又快速。比如,如果你想计算多项式的值:

def f(x):
    return 3*x**2 - 2*x + 7

print(f(ax))#[ 8 15 28 47]

Numpy还为数组操作提供了大量的通用函数,这些函数可以作为math模块中类似函数的替代

print(np.sqrt(ax))#[ 1.          1.41421356  1.73205081  2.        ]
print(np.cos(ax))#[ 0.54030231 -0.41614684 -0.9899925  -0.65364362]
Numpy扩展Python列表的索引功能
3.10矩阵与线性代数运算

  执行矩阵和线性代数的运算,比如矩阵乘法、寻找行列式、求解线性方程组等等。
  numpy库有一个矩阵对象可以用来解决这个问题

m = np.matrix([[1,-2,3],[0,4,5],[7,8,-9]])
print(m)
print('矩阵的转置transpose')
print(m.T)
print('矩阵的逆inverse')
print(m.I)
print('Create a vector and multiply')
v = np.matrix([[2],[3],[4]])
print(v)
print('矩阵的乘法')
print(m*v)

输出如下

[[ 1 -2 3]
[ 0 4 5]
[ 7 8 -9]]
矩阵的转置transpose
[[ 1 0 7]
[-2 4 8]
[ 3 5 -9]]
矩阵的逆inverse
[[ 0.33043478 -0.02608696 0.09565217]
[-0.15217391 0.13043478 0.02173913]
[ 0.12173913 0.09565217 -0.0173913 ]]
Create a vector and multiply
[[2]
[3]
[4]]
矩阵的乘法
[[ 8]
[32]
[ 2]]

3.11随机选择

  你想从一个序列中随机抽取若干元素,或者想生成几个随机数
  random模块有大量的函数用来生产随机数和随机选择元素。
  可以使用random.choice()来随机的抽取一个元素。使用random.sample()来踢去出N个不同的元素

values = [1,2,3,4,5,6]
print(random.choice(values))#2 随机的
print(random.sample(values,3))#[5, 3, 4]  随机的

  如果你想打乱序列中元素的位置,可以使用random.shuffle()

random.shuffle(values)
print(values)#[2, 4, 5, 1, 6, 3]

生成随机整数,可以使用random.randint()
生成0到1范围内均匀分布的浮点书,使用random.random()
如果要获取N位随机位(二进制)的整数,使用random.getrandbits()

print(random.randint(0,4))
print(random.random())
print(random.getrandbits(6))

random模块使用Mersenne Twister算法来计算生成随机数。这是一个确定性算法,但是,你可以通过random.seed()函数修改初始化种子。
除了上述功能,random模块还包括基于均匀分布、高斯分布的随机数生成函数。比如,random.uniform计算均匀分布随机数,random.gauss()计算正态分布随机数。

注:在random模块中的函数不应该用在和密码学相关的程序中。如果你确实需要类似的功能,可以使用ssl模块中相应的函数。比如ssl.RAND_bytes()可以用来生成一个安全的随机字节序列

3.12基本的日期与时间转换

  当需要执行简单的时间转换,比如天到秒,小时到分钟等的转换的时候,可以使用datetime模块。比如,为了表示一个时间短,可以创建一个timedelta实例:

from datetime import timedelta
a = timedelta(days=2,hours=5)
b = timedelta(hours=4.5)
c = a + b
print(a)#2 days, 5:00:00
print(b.seconds)#16200
print(a.seconds)#18000
print(c.seconds/3600)#9.5 小时 并不包含天
print(c.total_seconds()/3600) # 57.5小时,包含天

如果你想表示指定的日期和时间,先创建一个datetime实例,然后使用标准的数学运算来操作它们。

from datetime import datetime,timedelta
a = datetime(2017,7,11)
print(a+timedelta(days=10))#2017-07-21 00:00:00
b = datetime(2017,6,11)
d = a - b
print(d)#30 days, 0:00:00

now = datetime.today()
print(now)#2017-07-11 14:52:16.567548
print(now + timedelta(minutes=20))#2017-07-11 15:12:16.567548

在计算的时候,datetime会自动处理闰年
对于大多数基本的日期和时间处理问题,datetime模块已经足够了。如果你需要执行更加复杂的日期操作,比如处理时区,模糊时间范围,节假日计算等等,可以考虑使用dateutil模块

3.13计算最后一个周五的日期
from datetime import datetime,timedelta
from dateutil.relativedelta import relativedelta
from dateutil.rrule import *
now = datetime.now()
toady = datetime.today()
print(now)
print(toady)#2017-07-11 15:08:05.218067
print(now + relativedelta(weekday=FR))#2017-07-14 15:08:05.218055
print(now + relativedelta(weekday=FR(-1)))#2017-07-07 15:08:05.218055

3.14计算当前月份的日期范围
3.15字符串转换为日期

使用datetime可以解决这个问题。

text = '2017-7-11'
y = datetime.strptime(text,'%Y-%m-%d')
print(y)

datetime.strptime()方法支持很多的格式化代码,比如%Y代表4位数年份,%m代表两位数月份。并且,这个格式化占位符也可以反过来使用。

3.16结合时区的日期操作
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容