📖 前言:本期将简要介绍python的语法,由于已经学过C语言,部分重复语法仅介绍异同,不再重复。
推荐一个在线Python编程的网站🔎 菜鸟教程在线编程
目录
🕒 1. Python基本语法
🕘 1.1 缩进
python与C最大的不同就是编译所使用的方法, C语言中每一句代码的结尾都需要;而Python代码是一行一行执行,不需要;
Python使用缩进
表示代码块,C语言使用一对花括号{ }
c语言:
int main{
printf("hello!");
}
python:
print('hello!')
- 一个语句占一行
- 单个语句占多行,用反斜杠
\
- 多个语句在一行,使用分号
;
分隔
t = a + \
b + \
c
🕘 1.2 注释
- 单行注释用
#
- 多行注释用三个单引号
'''
或者三个双引号"""
将注释括起来
# 单行注释 print ("Hello, Python!")
'''
多行注释,
使用三单引号。
'''
"""
多行注释,
使用双引号。
"""
🕘 1.3 变量的声明
C语言每次进行定义变量的时候,都需要声明其数据类型。
但是在Python中不需要
声明其数据类型,但必须赋值。赋值的时候Python会自动
给它分配相应的数据类型
a = 1 # 整型变量
b = 10.0 # 浮点型变量
c = "abc" # 字符串
基本数据类型:
- 数字(number)
- 整数(int):2,59,100,-3
- 小数(float):0.4,5.0,-0.78
- 布尔(bool):True,False
- 字符串(string):”How are you?”,'this is a string.’ (单引号 or 双引号)
容器类型:(除元组外均为可变类型)
- 列表(list):[1, 2, 5, 10]
- 元组(tuple):(1, ‘two’)
(内容不可修改)
- 集合(set):{‘Mike’, ‘John’, ‘Marry’}
- 字典(dictionary):{‘20120010’: 98, ‘20120011’: 89, ‘20120023’:100}
可变类型:V=M,M数据地址传递给V(V和M指向相同地址数据块)修改V中的数据将导致M数据也发生改变;函数传参时传地址而非传值
🕘 1.4 运算符与表达式
🕤 1.4.1 算术
+-*/ #(加减乘除,其中 / 返回一个浮点数)
% #(取模)
** #(幂) 对应C语言 pow
// #(取整除)
🕤 1.4.2 布尔
True
和False
为预定义值;实际上是整数1
和0
- 比较运算符:
<、<=、>、>=、==、!=
,结果是布尔值 - 布尔运算符:
and
(布尔与)、or
(布尔或)、not
(布尔非)
🕘 1.5 字符串
- 字符串用单引号
'
或双引号"
括起来 - 使用反斜杠
\
转义特殊字符:\n 换行符,\t 制表符,…… - 三引号用于大块的文本内容
b = """One line,
another line."""
print(b)
🕤 1.5.1 字符串运算
- 使用
+
进行连接
- 星号
*
进行复制
# 字符串拼接
a = "Part 1"
b = "and part 2"
print(a + ' ' + b) # 对应C语言strncat函数 运行结果:Part 1 and part 2
# 字符串重复并拼接
s = a * 2
print(s) # 运行结果:Part 1Part 1
# 提取子串
s[0]
print(s[0:4]) # 数组下标范围是 0 <= s <4 即 Part
print(s[5:]) # 数组下标范围是 s >= 5 即1Part 1
print(s[6:-1]) # 数组下标范围是 6 <= s < 倒1 即 Part
# 字符串长度
len(s) # 对应C语言strlen函数,运行结果:12
# 子串检测
'p' in s # 运行结果:False
'P' in s # 运行结果:True
'Part' in s # 运行结果:True
注:print 默认输出是换行的。如果要实现不换行在变量末尾加上 end=“”
#如果要实现不换行:
print ('counter',end=" ")#Python3:在变量末尾加上 ,end=""
🕤 1.5.2 字符串不能改变
# 直接修改字符串会报错
s = "Hello Python"
s[0] = 'B'
# 如果要修改,需要构建新字符串
s = 'B' + s[1:] # 结果:把H改成B
# 如果要生成许多新串,尝试字符串格式化
Hello = 'Hello'
Python = 'Python'
# 字符串格式化
hp12 = '%s %s %d' % (Hello, Python, 12)
print(hp12)
- 列表(List)处理能让字符串处理更为有效
🕤 1.5.3 字符串的方法
- 字符串有一组内建(built-in)方法
- 没有方法可以改变原串,有几个方法可以生成新串
s = 'a string, with stuff'
s.count('st') # 有多少子串? st 有两个
s.find('stu') # 寻找子串,如果有,给出子串的位置,结果是15(stu的s前面的空格)
s.replace('stuff', 'characters') # 替换子串 (全部出现过的子串),结果:a string, with characters
s.replace('s', 'X', 1) # 只替换一次,结果:a Xtring, with stuff
s = '3'
s.isdigit() # 是纯数字串吗? 结果:True
s = "hello"
print(s.capitalize()) # 首字母大写;输出"Hello"
print(s.upper()) # 所有字符转换成大写字符;输出"HELLO"
print(s.rjust(7)) # 右对齐,左端补空格;输出" hello"
print(s.center(7)) # 居中对齐,左右两端补空格;输出" hello "
print(' world '.strip()) # 去除前后的所有空白符;输出"world"
🕘 1.6 列表
- 有序的对象序列
- 异质的;可以包含任意类型的对象的混合
r = [1, 2.0, 3, 5] # 列表实例,不同的值
print(type(r)) # 输出<class 'list'>
t = (1, 3, 2) # 元组实例,不同的值
print(type(t)) # 输出<class 'tuple'>
r[1] # 通过下标来访问; 偏移量为 0
r[-1] # 负的下标代表从尾部开始计数
r[1:3] # 列表的片段; 给出新的列表
w = r + [10, 19] # 合并列表; 给出另外的一个列表
w
r # 原列表不变; w 和 r 不同
t = [0.0] * 10 # 用重复生成一个初始向量
t
🕤 1.6.1 列表操作
- 列表是可变的,可以改变局部
r = [1, 2.0, 3, 5]
r[3] = 'word' # 通过下标改变一个元素(项)
r # 显示[1, 2.0, 3, 'word']
r[0] = [9, 8] # 列表可以嵌套
r # 显示[[9, 8], 2.0, 3, 'word']
r[0:3] = [1, 2, 5, 6] # 改变列表的一个片段,可以改变列表的长度
r # 显示[1, 2, 5, 6, 'word']
r[1:3] = [] # 通过设置列表的片段为空集来移除元素
r # 显示[1, 6, 'word']
len(r) # 列表的长度,即项的个数,显示3
6 in r # 成员测试,显示True
r.index(6) # 搜索并给出位置,如果没有的话,报错,这里显示1
🕤 1.6.2 列表的方法
r = [1, 2.0, 3, 5]
r.append('thing') # 在列表尾增加一个项
r # 显示[1, 2.0, 3, 5, 'thing']
r.append(['another', 'list']) # 增加的列表被看作一个单一项
r # 显示[1, 2.0, 3, 5, 'thing', ['another', 'list']]
r = [1, 2.0, 3, 5]
r.extend(['item', 'another']) # 列表的项逐次添加
r # 显示[1, 2.0, 3, 5, 'item', 'another']
k = r.pop() # 移除最后一项
k # 显示'another'
r # 显示[1, 2.0, 3, 5, 'item']
r.insert(3, 4.0) # 在指定位置插入一项
r # 显示[1, 2.0, 3, 4.0, 5, 'item']
r.remove('item') # 删除一项
r # 显示[1, 2.0, 3, 4.0, 5]
- 使用内建的sort方法:排序是内部进行的,不产生新列表!
- 外部函数sorted,不改变原列表的顺序 Sorted的使用
r = [2, 5, -1, 0, 20]
r.sort()
r # 显示[-1, 0, 2, 5, 20]
w = ['apa', '1', '2', '1234']
w.sort() # 字符串: 使用ASCII顺序
w # 显示['1', '1234', '2', 'apa']
w.reverse() # 反转列表!
w # 显示['apa', '2', '1234', '1']
v = w[:] # 首先生成新表
v.reverse() # 反转这份拷贝
v # 显示['1', '1234', '2', 'apa']
w # 显示['apa', '2', '1234', '1']
🕤 1.6.3 转换字符串为列表
s = 'biovitrum' # 生成字符串
w = list(s) # 转为字符的列表
w # 显示['b', 'i', 'o', 'v', 'i', 't', 'r', 'u', 'm']
w.reverse()
w # 显示['m', 'u', 'r', 't', 'i', 'v', 'o', 'i', 'b']
r = ''.join(w) # 使用空串的join方法
r # 显示'murtivoib'
d = '-'.join(w) # 使用字符-的join方法
d # 显示'm-u-r-t-i-v-o-i-b'
s = 'a few words'
w = s.split() # 基于空白符(空格, 新行)切分
w # 显示['a', 'few', 'words']
' | '.join(w) # 对其他串用方法'join',显示'a | few | words'
🕘 1.7 元组
- 和列表一样,只是
不可变
,即一旦生成,就不可改变 - 某些函数会返回元组
t = (1, 3, 2)
t[1] # 由下标访问,偏移量从0开始,显示3
(a, b, c) = t # 元组赋值
a # 显示1
b # 显示3
a, b, c # 一个实际上的元组表达式,显示(1, 3, 2)
a, b = b, a # 交换值的技巧
a, b # 显示(3, 1)
r = list(t) # 转换元组为列表
r # 显示[1, 3, 2]
tuple(r) # 转换列表为元组,显示(1, 3, 2)
🕘 1.7 集合
- 一个
无序
的没有重复元素
的序列 - 基本功能是进行成员关系测试和删除重复元素,可以进行集合运算
student = {'Tom', 'Jim', 'Mary', 'Tom', 'Jack', 'Rose'}
print(student) # 输出集合,重复元素被自动去掉
{'Mary', 'Jim', 'Rose', 'Jack', 'Tom'}
print('Rose' in student) # 成员测试,结构是True
a = set('abracadabra') # 字符串转换成集合
b = set('alacazam')
print(a) # {'b', 'a', 'c', 'r', 'd'}
print(a - b) # a和b的差集,结果:{'b', 'd', 'r'}
print(a | b) # a和b的并集,结果:{'l', 'r', 'a', 'c', 'z', 'm', 'b', 'd'}
print(a & b) # a和b的交集,结果:{'a', 'c'}
print(a ^ b) # a和b中不同时存在的元素,结果:{'l', 'r', 'z', 'm', 'b', 'd'}
🕘 1.8 字典
- 键(key)值(value)对的
无序集合
- 键必须使用
不可变
类型。可以用数字、字符串或元组
,不能用列表
- 在同一个字典中,
键
必须是唯一
的,值不必
h = {'key': 12, 'nyckel': 'word'}
h['key'] # 由键访问,显示12
print('nyckel' in h) # 显示True
# 增加一个键/值
h['Per'] = 'Kraulis'
print(h) # 输出顺序是随机的,结果:{'key': 12, 'nyckel': 'word', 'Per': 'Kraulis'}
# 替换一个键对应的值
h['Per'] = 'Johansson'
print(h) # 结果:{'key': 12, 'nyckel': 'word', 'Per': 'Johansson'}
🕤 1.8.1 字典的方法
h = {'key': 12, 'nyckel': 'word'}
'Per' in h # 测试一个键是否在字典中,显示False
h['Per'] # 报错
h.get('Per', 'unknown') # 返回值, 或者返回缺省值,显示'unknown'
h.get('key', 'unknown') # 显示12
h.keys() # 字典中所有的键,结果:['nyckel', 'key']
h.values() # 字典中所有的值,结果:['word', 12]
h.items() # 字典中所有的键值对,结果:dict_items([('key', 12), ('nyckel', 'word')])
len(h) # 字典中键值对的个数,显示2
g = h.copy() # 拷贝字典
del h['key']
h # 显示{'nyckel': 'word'}
g # 显示{'nyckel': 'word', 'key': 12}
h['Per'] = 'Johansson'
h # 显示{'nyckel': 'word', 'Per': 'Johansson'}
h.update(g) # 根据g添加或者更新所有的键值
h # 显示{'nyckel': 'word', 'key': 12, 'Per': 'Johansson'}
g.clear() # 清除字典中的所有项
print(len(g)) # 显示0
删除数据的命令:del
- 命令!不是函数!
- 实际上移除变量(名字),不是对象
a = 'thing' # 定义一个变量
a # 显示'thing'
del a # 把这个变量忘掉
a # 报错
h = {'key': 12, 'nyckel': 'word'}
del h['key'] # 移除键和它的值
h # 显示{'nyckel': 'word'}
r = [1, 3, 2]
del r[1] # 另一个删除列表项的方式
r # [1, 2]
🕘 1.9 条件语句 if
age = 12
if age < 4:
print("Your admission cost is $0.")
elif age < 18:
print("Your admission cost is $5.")
else:
print("Your admission cost is $10.")
🕘 1.10 循环语句
🕤 1.10.1 while
current_number = 1
while current_number <= 5:
print(current_number)
pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
print(pets)
while 'cat' in pets:
pets.remove('cat')
print(pets) # 结果:['dog', 'dog', 'goldfish', 'rabbit']
🕤 1.10.2 for
for 变量名 in 可迭代对象:
# 对每个变量做一些事情
# ...
students = ['Alice', 'Bob', 'LiHua']
for student in students:
print(student.title() + ", Welcome to Zhku!")
squares = []
for value in range(1,11):
squares.append(value**2)
print(squares) # 结果:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
r = []
for c in 'this is a string with blanks': # 一个字符一个字符地遍历字符串
if c == ' ': continue # 跳过后面的代码块,继续循环
r.append(c)
print (''.join(r)) # thisisastringwithblanks
循环中的break, continue和else
- break语句跳出循环
- continue语句结束本轮循环,开始下一轮循环
- else在循环条件不满足时被执行,被break的循环不执行else
- pass语句是空语句,什么都不做,占位语句
r = [1, 3, 10, 98, -2, 48]
for i in r:
if i < 0:
print ('input contains negative value!')
break # 跳出整个循环,包括'else'
else:
pass # 什么都不做
else: # 如果循环是正常结束的,则执行
print ('input is OK')
列表循环与List Comprehension
nums = [0, 1, 2, 3, 4]
squares = []
for x in nums:
squares.append(x ** 2)
print(squares) # Prints [0, 1, 4, 9, 16]
nums = [0, 1, 2, 3, 4]
squares = [x ** 2 for x in nums]
print(squares) # Prints [0, 1, 4, 9, 16]
nums = [0, 1, 2, 3, 4]
even_squares = [x ** 2 for x in nums if x % 2 == 0]
print(even_squares) # Prints [0, 4, 16]
animals = ['cat', 'dog', 'monkey']
for idx, animal in enumerate(animals): # enumerate(objs)返回(idx,obj)
print('#%d: %s' % (idx + 1, animal))
字典循环与Dictionary Comprehension
d = {'person': 2, 'cat': 4, 'spider': 8}
for animal in d:
legs = d[animal]
print('A %s has %d legs' % (animal, legs))
d = {'person': 2, 'cat': 4, 'spider': 8}
for animal, legs in d.items():
print('A %s has %d legs' % (animal, legs))
nums = [0, 1, 2, 3, 4]
even_num_to_square = {x: x ** 2 for x in nums if x % 2 == 0}
print(even_num_to_square) # Prints {0: 0, 2: 4, 4: 16}
集合循环与Set Comprehension
animals = {'cat', 'dog', 'fish'}
for idx, animal in enumerate(animals):
print('#%d: %s' % (idx + 1, animal))
from math import sqrt
nums = {int(sqrt(x)) for x in range(30)}
print(nums) # Prints {0, 1, 2, 3, 4, 5}
🕘 1.11 函数
def greet_user():
print("Hello!")
greet_user()
def greet_user(username):
print("Hello, " + username.title() + "!") # title函数,返回(标题化)的字符串,就是单词的开头为大写,其余为小写
greet_user('jesse') # 结果:Hello, Jesse!
def describe_pet(animal_type, pet_name):
print("\nI have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet('hamster', 'harry')
describe_pet('dog', 'willie')
🕤 1.11.1 函数参数的默认值
- 参数可以有默认值
- 当调用时没有给定参数,会采用默认值
- 有默认值的参数必须放在参数列表的最后
- 显式调用参数,可以改变参数顺序
def describe_pet(pet_name, animal_type='dog'):
print("\nI have a " + animal_type + ".")
print("My " +animal_type+ "'s name is " + pet_name.title()+ ".")
describe_pet('willie')
describe_pet(pet_name='harry', animal_type='hamster')
describe_pet(animal_type='hamster', pet_name='harry')
🕤 1.11.2 函数返回值
- 一个函数不一定要有return语句
- 实际上,函数默认总会返回一个值:‘None’
- ‘None’ 是一个特殊的值,意味着 ‘什么都没有’
def get_formatted_name(first_name, last_name):
full_name = first_name + ' ' + last_name
return full_name.title()
musician = get_formatted_name('jimi', 'hendrix')
print(musician) # 结果:Jimi Hendrix
🕤 1.11.3 模块/库函数
- 将函数存储在被称为模块的独立文件中,再将模块导入到主程序中
- 数学函数在一个单独的模块中
import math # 导入整个'math'模块
print (math.e, math.pi) # 自然对数e,π
print (math.cos(math.radians(180.0))) # cos(180°)
print (math.log(10.0)) # 以e为底10的对数
print (math.exp(-1.0)) # e的-1次幂
from math import * # 导入模块'math'中的所有函数
print (e, pi)
print (cos(radians(180.0)))
print (log(10.0))
print (exp(-1.0))
from math import log, cos # 导入'math'模块中的log和cos函数
from math import log as lg # 导入'math'模块中的log函数,起别名lg
🕘 1.12 文件操作
🕤 1.12.1 读
- 一个文件操作对象由内建函数 ‘open’ 创建
- 文件对象有一系列函数
- ‘read’:读取整个文件 (或者说N 字节),返回一个单独的字符串
- ‘readline’:读取一行(然后跳到新的一行)
- ‘readlines’:读取所有的行,返回一个字符串的列表
f = open('test.txt') # 默认: 只读模式
line = f.readline() # 读一行
line # 显示'This is the first line.\n'
lines = f.readlines() # 读所有剩余行
lines # 显示['This is the second.\n', 'And third.\n']
🕤 1.12.2 写
- ‘write’ 函数只是简单地输出给定字符串
- 字符串不一定是ASCII码,二进制串也可以
w = open('output.txt', 'w') # 写模式 (默认写的是文本)
w.write('stuff') # 并不自动添加新行
w.write('\n')
w.write('more\n and even more\n')
w.close()
🕤 1.12.3 用for循环读取文件
infile = open('test.txt') # 只读模式
outfile = open('test_upper.txt', 'w') # 写模式; 创建文件
for line in infile: # 遍历文件中的每一行
outfile.write(line.upper())
infile.close() # 并不严格要求; 系统会自动执行
outfile.close()
- 注意: 每行结尾会尾随一个换行符 ‘\n’
- 可以使用字符串方法’strip’或者’rstrip’去除它
小结
列表
用 “[ ]
” 标识类似 C 语言中的数组;
元组
用 “( )
” 标识。内部元素用逗号隔开。但是元组不能二次赋值
,相当于只读
列表;
字典
用 “{ }
” 标识。字典由索引 key 和它对应的值 value 组成
非数字型
的共同点:都可以使用切片、链接(+)、重复(*)、取值(a[])等相关运算;
非数字型的不同点:列表
可以直接赋值,元组
不可以赋值,字典
按照 dict[k]=v 的方式赋值。
参考资料与教程
Python文档:https://docs.python.org/3/
“用Python玩转数据”:
https://www.coursera.org/learn/hipython/
《Python编程:从入门到实践》
第2、3、4、5、6、7、8章
🕒 2. Python库的简介
🕘 2.1 Numpy
Numpy:高效地处理高维数组;高效的数学函数
Quickstart tutorial:https://docs.scipy.org/doc/numpy/user/quickstart.html
A Visual Intro to NumPy and Data Representation:http://jalammar.github.io/visual-numpy/
Numpy(Numerical Python extensions)是一个第三方的Python包,用于科学计算,前身是1995年就开始开发的一个用于数组运算的库
极大地简化了向量和矩阵的操作处理,是一些主力软件包(如scikit-learn、Scipy、pandas和tensorflow)架构的基础部分。
ndarray 数据类型
Numpy提供了一种新的数据结构:ndarray(n维数组,n-dimensional array)
不同于列表和元组,数组只能存放相同类型
的对象(如全部整型或全部浮点型)
这使得在数组上的一些运算远远快于在列表上的相同运算;另外,数组占用更小的存储
数组强有力地扩展了列表的索引机制
🕤 2.1.1 创建n维数组
import numpy as np
a = np.array([2, 3, 6, 7])
print(a) # 创建一维数组
b = np.array([2, 3, 6, 7.])
print(b)
c = np.array([2, 3, 6, 7+1j])
print(c)
np.zeros(3) # 用0填充1维数组,1行3列
np.ones((2,3)) # 用1填充2维数组,2行3列
🕤 2.1.2 创建等差数列的数组
格式:arange([start,] stop[, step,], dtype=None)
a = np.arange(5)
print(a)
b = np.arange(10, 100, 20, dtype=float)
print(b)
c = np.arange(15).reshape(3,5) # 重新排列为3行5列的矩阵
print(c)
格式:linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
c=np.linspace(0., 2.5, 5)
print(c) # 输出:[0. 0.625 1.25 1.875 2.5 ]
from numpy import pi
x = np.linspace( 0, 2*pi, 100 ) # 用于在多个点执行某函数
f = np.sin(x)
print(x)
print(f)
🕤 2.1.3 多维数组表示的矩阵
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a)
print(a.shape) # 行数和列数
print(a.ndim) # 维数
print(a.size) # 元素数
🕤 2.1.4 改变形状
import numpy as np
a = np.arange(0, 20, 1) # 一维数组
print(a)
b = a.reshape((4, 5)) # 4行,5列
print(b)
c = a.reshape((20, 1)) # 2维
print(c)
d = a.reshape((-1, 4)) # -1: 自动决定行数
print(d)
a.shape = (4, 5) # 改变a的形状
print(a)
形状(N, ), (N, 1)和(1, N)不同
- 形状(N, ):数组是一维的
- 形状(N, 1):数组是二维的,N行一列
- 形状(1, N):数组是二维的,一行N列
a = np.array([1, 2, 3, 4, 5]) # 一维数组
b = a.copy()
c1 = np.dot(np.transpose(a), b) # 转置对一维数组不起作用
print(c1)
c2 = np.dot(a, np.transpose(b)) # 转置也可以写成b.T
print(c2)
ax = np.reshape(a, (5, 1))
bx = np.reshape(b, (1, 5))
c = np.dot(ax, bx)
print(c)
🕤 2.1.5 用相同元素填充数组
a = np.zeros(3)
print(a)
b = np.zeros((2, 2), complex)
print(b)
c = np.ones((2, 3))
print(c)
d = np.full((2,2), 7)
print(d)
🕤 2.1.6 用随机数填充数组
- rand:0到1之间[0, 1)均匀分布的随机数
- randn:服从均值为0,方差为1的标准正态(高斯)分布的随机数
- 也有其他标准概率分布的随机数
a = np.random.rand(2,4)
print(a)
b = np.random.randn(2,4)
print(b)
🕤 2.1.7 一维数组索引与切片
[start : stop]的索引形式可用于从数组中抽取片段(从start位置开始直到stop位置但不包括stop)
a = np.array([0, 1, 2, 3, 4])
a[1:3] # array([1, 2])
a[:3] # array([0, 1, 2])
a[1:] # array([1, 2, 3, 4])
a[1:-1] # array([1, 2, 3])
整个数组:a或者a[:]
a = np.array([0, 1, 2, 3, 4])
a[:] # array([0, 1, 2, 3, 4])
想取出间隔的元素,可以在第二个冒号之后说明第三个数(步长):
a[::2] # array([0, 2, 4])
a[1:4:2] # array([1, 3])
步长-1,可用于反转一个数组:
a[::-1] # array([4, 3, 2, 1, 0])
🕤 2.1.8 二维数组的索引与切片
- 多维数组的索引是整数元组
a = np.arange(12); a.shape = (3, 4);
print(a)
'''array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])'''
a[1, 2] # 6
a[1, -1] # 7
- 切片:单行单列,和列表类似
a = np.arange(12); a.shape = (3, 4);
print(a)
'''array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])'''
a[:, 1] # array([1, 5, 9])
a[2, :] # array([8, 9, 10, 11])
a[1][2] # 6
a[2] # array([8, 9, 10, 11])
🕤 2.1.9 拷贝与视图
- 标准列表的一个切片是它的一个拷贝
- Numpy数组的一个切片是数组上的一个视图,切片数组和原始数组都引用的是同一块内存区域。因而,当改变视图内容时,原始数组的内容也被同样改变了:
a = np.arange(5);
print(a) # array([0, 1, 2, 3, 4])
b = a[2:];
print(b) # array([2, 3, 4])
b[0] = 100;
print(b) # array([100, 3, 4])
print(a) # array([0, 1, 100, 3, 4])
- 为了避免改变原数组,可以拷贝切片:
a = np.arange(5);
print(a) # array([0, 1, 2, 3, 4])
b = a[2:].copy();
print(b) # array([2, 3, 4])
b[0] = 100;
print(b) # array([100, 3, 4])
print(a) # array([0, 1, 2, 3, 4])
🕤 2.1.10 数组计算
- 基本的算术运算都作用在数组的元素级别
x = np.array([[1,2],[3,4]], dtype=np.float64)
y = np.array([[5,6],[7,8]], dtype=np.float64)
print(x + y)
print(np.add(x, y))
print(x - y)
print(np.subtract(x, y))
print(x * y)
print(np.multiply(x, y))
print(x / y)
print(np.divide(x, y))
print(np.sqrt(x))
🕤 2.1.11 矩阵乘法
- 矩阵乘法是使用dot函数实现的:
A = np.array([[1, 2], [3, 4]])
print(np.dot(A, A))
'''array([[7, 10],
[15, 22]])'''
- dot函数也可用于矩阵和向量的乘法:
a = np.array([[1, 2],
[3, 4]])
x = np.array([[5, 6],
[7, 8]])
print(np.dot(A, x)) #等价于A.dot(x)
'''array[[19 22]
[43 50]]'''
print(np.dot(x, A)) #等价于x.dot(A)
'''array[[23 34]
[31 46]]'''
🕤 2.1.12 数组快速求和
x = np.array([[1,2],[3,4]])
print(np.sum(x)) # 输出所有元素的和; 结果:10
print(np.sum(x, axis=0)) # 输出每列元素的和; 结果:[4 6]
print(np.sum(x, axis=1)) # 输出每行元素的和; 结果:[3 7]
🕤 2.1.13 保存数组到文件
savetxt()
函数将一个数组保存到一个文本文件中:
a = np.linspace(0, 1, 12); a.shape = (3, 4); a
'''array([[ 0. , 0.09090909, 0.18181818, 0.27272727],
[ 0.36363636, 0.45454545, 0.54545455, 0.63636364],
[ 0.72727273, 0.81818182, 0.90909091, 1. ]])'''
np.savetxt(“myfile.txt”, a)
- 其他格式的文件也可以(参见文档)
save()
函数将一个数组存成一个Numpy的“.npy”格式的二进制文件:
np.save(“myfile”, a)
- 生成一个二进制文件myfile.npy包含数组a,之后可以使用
np.load()
函数读入内存
🕤 2.1.14 从文本文件读入数组
loadtxt()
函数把一个存成文本文件的数组读入内存- 缺省地,该函数假设列是用空白符分隔的。可以通过修改可选的参数来改变此假设。#开头的行被忽略。
- 示例文本文件data.txt:
# Year Min temp. Max temp.
1990 -1.5 25.3
1991 -3.2 21.2
table = np.loadtxt(“data.txt”)
'''
array([[1.99000000e+03, -1.50000000e+00, 2.53000000e+01],
[1.99100000e+03, -3.20000000e+00, 2.12000000e+01]])'''
🕤 2.1.15 小结
- Numpy中包含许多常用的数学函数,例如:np.log, np.maximum, np.sin, np.exp, np.abs等等(详见: https://docs.scipy.org/doc/numpy/reference/routines.math.html )
- 大多数情况下,Numpy中的函数比math库中类似的函数更高效,尤其是处理大规模数据时。
🕘 2.2 Matplotlib
Matplotlib是Python中最常用的可视化工具之一,可以非常方便地创建海量类型的2D图表和一些基本的3D图表
因为在函数的设计上参考了MATLAB,所以叫做Matplotlib
首次发表于2007年,是为了可视化癫痫病人的脑皮层电图相关的信号而研发的,原作者John D. Hunter博士是一名神经生物学家
🕤 2.2.1 最简单的图表
import matplotlib.pyplot as plt
plt.plot([1,2,3,4], [1,4,9,16], 'ro')
plt.axis([0, 6, 0, 20])
plt.show()
🕤 2.2.2 一张表中的多个函数
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(0., 5., 0.2)
plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
plt.show()
设置线条属性
- 使用键值对参数:
plt.plot(x, y, linewidth=2.0)
- 使用Line2D类对象的属性设置方法:
line, = plt.plot(x, y, '-')
line.set_antialiased(False) # turn off antialiasing
- 使用setp()命令:
lines = plt.plot(x1, y1, x2, y2)
# use keyword args
plt.setp(lines, color='r', linewidth=2.0)
# or MATLAB style string value pairs
plt.setp(lines, 'color', 'r', 'linewidth', 2.0)
# Compute the x and y coordinates for points on sine and cosine curves
x = np.arange(0, 3 * np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)
# Plot the points using matplotlib
plt.plot(x, y_sin)
plt.plot(x, y_cos)
plt.xlabel('x axis label')
plt.ylabel('y axis label')
plt.title('Sine and Cosine')
plt.legend(['Sine', 'Cosine'])
plt.show()
🕤 2.2.3 多张图表:子图表
def f(t):
return np.exp(-t) * np.cos(2*np.pi*t)
t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)
plt.figure(1)
plt.subplot(211)
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')
plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.show()
🕤 2.2.4 绘制分类变量的图表
🕤 2.2.5 添加文本
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
# the histogram of the data
n, bins, patches = plt.hist(x, 50, density=1, facecolor='g', alpha=0.75)
plt.xlabel('Smarts')
plt.ylabel('Probability')
plt.title('Histogram of IQ')
plt.text(60, .025, r'$\mu=100,\ \sigma=15$')
plt.axis([40, 160, 0, 0.03])
plt.grid(True)
plt.show()
🕤 2.2.5 添加文本注释
ax = plt.subplot(111)
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = plt.plot(t, s, lw=2)
plt.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
arrowprops=dict(facecolor='black', shrink=0.05))
plt.ylim(-2,2)
plt.show()
🕤 2.2.6 图像显示
import matplotlib.pyplot as plt
plt.figure('A Cute Cat')
Cute_Cat_img = plt.imread('cute cat.jpg')
plt.imshow(Cute_Cat_img)
plt.show()
根据可视化专家 Andrew Abela 对该数据关系分类方式的提炼,他提出将图表展示的数据关系分为四类:比较、分布、构成和联系。下面对这四种关系以及应用举例和对应的可视化解决方案做了简要的分析。
🕘 2.3 Pandas
Pandas是python的一个数据分析包
由AQR Capital Management于2008年4月开发,并于2009年底开源出来
导入惯例:from pandas import Series, DataFrame import pandas as pd
因为Series和DataFrame用的次数非常多,所以将其引入本地命名空间中会更方便
🕤 2.3.1 常用数据结构
- Series
- 一维标记数组,由一组数据(各种NumPy数据类型)以及一组与之相关的数据标签(即索引)组成。
- 类似于Numpy中的一维数组和Python的列表,不同之处是数组和series中存放的是相同类型的元素
- DataFrame
- 二维表格型数据结构, 含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等),
- 每列都有标签,可看成一个Series的字典
- Panel
- 三维数组,可以理解为DataFrame的容器
- Panel data源于经济学,也是pan(el)-da(ta)-s的名字来源
🕤 2.3.2 创建Series:传入列表
- 默认整型指引
obj = Series([4, 7, -5, 3])
print(obj)
'''obj
0 4
1 7
2 -5
3 3
dtype: int64'''
obj.values # array([4, 7, -5, 3], dtype=int64)
obj.index # RangeIndex(start=0, stop=4, step=1)
- 给定索引
obj2 = Series([4,7,-5,3], index=['d','b','a','c'])
print(obj2)
'''
d 4
b 7
a -5
c 3
dtype: int64'''
obj2.index # Index(['d', 'b', 'a', 'c'], dtype='object')
🕤 2.3.3 访问Series中的元素
- 可以使用索引来选取Series中的单个或一组值
obj2['a'] # -5
obj2['d']= 6
obj2[['c','a','d']]
'''
c 3
a -5
d 6
dtype: int64'''
🕤 2.3.4 对Series的操作
- NumPy数组操作,如通过一个布尔数组过滤,纯量乘法,或使用数学函数,都会保持索引和值间的关联:
obj2[obj2 > 0]
'''
d 4
b 7
c 3
dtype: int64'''
obj2*2
'''
d 8
b 14
a -10
c 6
dtype: int64'''
np.exp(obj2)
'''
d 54.598150
b 1096.633158
a 0.006738
c 20.085537
dtype: float64'''
- 还可将Series看成是一个定长的有序字典,因为它是索引值到数据值的一个映射。它可以用在许多原本需要字典参数的函数中:
'b' in obj2 # True
'e' in obj2 # False
🕤 2.3.5 创建Series:传入字典
- 如果数据被存放在一个Python字典中,也可以直接通过这个字典来创建Series
- 如果只传入一个字典,则结果Series中的索引就是原字典的键(有序排列)
sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
obj3 = Series(sdata)
print(obj3)
'''
Ohio 35000
Oregon 16000
Texas 71000
Utah 5000
dtype: int64'''
- 下例中,sdata跟states索引相匹配的那3个值会被找出来并放到相应的位置上,但由于“California”所对应的sdata值找不到,所以其结果就为NaN(Not A Number,非数字)
states = ['California', 'Ohio', 'Oregon', 'Texas']
obj4 = Series(sdata, index=states)
print(obj4)
'''
California NaN
Ohio 35000
Oregon 16000
Texas 71000
dtype: float64'''
🕤 2.3.6 检测缺失数据
- pandas的
isnull
和notnull
函数可用于检测缺失数据 - Series也提供了类似的实例方法,如obj4.isnull()
pd.isnull(obj4)
'''
California True
Ohio False
Oregon False
Texas False
dtype: bool'''
pd.notnull(obj4)
'''
California False
Ohio True
Oregon True
Texas True
dtype: bool'''
🕤 2.3.7 自动对齐索引
- Series在算术运算中会自动对齐不同索引的数据
obj3
'''
Ohio 35000
Oregon 16000
Texas 71000
Utah 5000
dtype: int64'''
obj4
'''
California NaN
Ohio 35000
Oregon 16000
Texas 71000
dtype: float64'''
obj3 + obj4
'''
California NaN
Ohio 70000
Oregon 32000
Texas 142000
Utah NaN
dtype: float64'''
🕤 2.3.8 Series对象及其索引的name
obj4.name = 'population'
obj4.index.name = 'state'
obj4
'''
state
California NaN
Ohio 35000
Oregon 16000
Texas 71000
Name: population, dtype: float64'''
🕤 2.3.9 修改索引
obj
'''
0 4
1 7
2 -5
3 3'''
obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']
obj
'''
Bob 4
Steve 7
Jeff -5
Ryan 3
dtype: int64'''
🕤 2.3.10 创建DataFrame
- 如果指定了列序列,DataFrame的列就会按指定顺序排列
DataFrame(data, columns=['year', 'state', 'pop'])
- 跟Series一样,如果传入的列在数据中找不到,就会产生NaN值
frame2=DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
index=['one', 'two', 'three', 'four', 'five'])
frame2
'''
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Ohio 1.7 NaN
three 2002 Ohio 3.6 NaN
four 2001 Nevada 2.4 NaN
five 2002 Nevada 2.9 NaN'''
访问单列
- 通过字典记法或属性,可以将DataFrame的列获取为一个Series:
frame2['state']
'''
one Ohio
two Ohio
three Ohio
four Nevada
five Nevada
Name: state, dtype: object'''
frame2.year
'''
one 2000
two 2001
three 2002
four 2001
five 2002
Name: year, dtype: int64'''
访问单行
- 行也可以使用一些方法通过位置(iloc)或名字(loc)来检索
frame2.loc['three']
'''
year 2002
state Ohio
pop 3.6
debt NaN
Name: three, dtype: object'''
frame2.iloc[2]
'''
Out[15]:
year 2002
state Ohio
pop 3.6
debt NaN
Name: three, dtype: object'''
修改列
frame2['debt'] = 16.5
frame2
'''
year state pop debt
one 2000 Ohio 1.5 16.5
two 2001 Ohio 1.7 16.5
three 2002 Ohio 3.6 16.5
four 2001 Nevada 2.4 16.5
five 2002 Nevada 2.9 16.5'''
frame2['debt'] = np.arange(5)
frame2
'''
year state pop debt
one 2000 Ohio 1.5 0
two 2001 Ohio 1.7 1
three 2002 Ohio 3.6 2
four 2001 Nevada 2.4 3
five 2002 Nevada 2.9 4'''
val = Series([-1.2, -1.5, -1.7], index=[ 'two', 'four', 'five'])
frame2['debt'] = val
frame2
'''
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Ohio 1.7 -1.2
three 2002 Ohio 3.6 NaN
four 2001 Nevada 2.4 -1.5
five 2002 Nevada 2.9 -1.7'''
增加列和删除列
frame2['eastern'] = frame2.state == 'Ohio'
frame2
'''
year state pop debt eastern
one 2000 Ohio 1.5 NaN True
two 2001 Ohio 1.7 -1.2 True
three 2002 Ohio 3.6 NaN True
four 2001 Nevada 2.4 -1.5 False
five 2002 Nevada 2.9 -1.7 False'''
del frame2['eastern']
frame2
'''
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Ohio 1.7 -1.2
three 2002 Ohio 3.6 NaN
four 2001 Nevada 2.4 -1.5
five 2002 Nevada 2.9 -1.7'''
删除行或列
frame2.drop(['pop','debt'], axis=1) # 删除pop和debt列
'''
year state
one 2000 Ohio
two 2001 Ohio
three 2002 Ohio
four 2001 Nevada
five 2002 Nevada'''
frame2.drop(columns=['pop','debt']) # 删除pop和debt列
'''
year state
one 2000 Ohio
two 2001 Ohio
three 2002 Ohio
four 2001 Nevada
five 2002 Nevada'''
frame2.drop(['one', 'three', 'five'], axis=0) # 删除one, three, five行
'''
year state pop debt
two 2001 Ohio 1.7 -1.2
four 2001 Nevada 2.4 -1.5'''
frame2.drop([‘pop',‘debt'], axis=1, inplace=True)
- 传入嵌套字典(字典的字典),外部键会被解释为列索引,内部键会被解释为行索引:
pop = {'Nevada': {2001: 2.4, 2002: 2.9},
'Ohio': {2000: 1.5, 2001: 1.7, 2002:3.6}}
frame3 = DataFrame(pop)
frame3
'''
Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6'''
frame4 = DataFrame(pop, index=[2001, 2002, 2003])
frame4
'''
Nevada Ohio
2001 2.4 1.7
2002 2.9 3.6
2003 NaN NaN'''
🕤 2.3.11 缺失数据处理
删除任何有缺失数据的行:
frame3.dropna(how='any')
'''
Nevada Ohio
2001 2.4 1.7
2002 2.9 3.6'''
对缺失值进行填充:
frame3.fillna(value=5)
'''
Nevada Ohio
2000 5.0 1.5
2001 2.4 1.7
2002 2.9 3.6'''
判断哪些值是缺失值(nan):
pd.isna(frame3)
'''
Nevada Ohio
2000 True False
2001 False False
2002 False False'''
🕤 2.3.12 查看数据
- 查看DataFrame前n行或后n行:
frame.head(3);frame.tail(3)
- 查看DataFrame的索引、列以及底层的Numpy数据:
frame.index ;frame.columns ;frame.values
- 显示数据的快速统计汇总:
frame.describe()
对每一列数据进行统计,包括计数、均值、标准差、各个分位数等 - 转置数据:
frame.T
- 对轴排序:
frame.sort_index(axis=1, ascending=False)
,其中axis=1
表示对所有的列索引进行排序,下面的数也跟着发生移动。 - 对值排序:
frame.sort_values(by=‘Name')
对name这一列,从小到大进行排序
🕤 2.3.13 选择行与列
- 选取多行或多列:
frame[[‘state', ‘pop']]
,选择’state’和’pop’两列,结果是一个DataFrame
frame[0:3]
,选择前三行 - loc用标签选择数据:
frame.loc[‘one']
,选择索引为’one’的行
frame.loc[‘one', ‘pop']
,选择‘one’行,'pop’列
frame.loc[:, [‘state', ‘pop']]
,选择所有行,'state’和’pop’列
frame.loc[[‘one', ‘two'], [‘state', ‘pop']]
,选择’one’和’two’行,'state’和’pop’列 - iloc用位置选择数据:
frame.iloc[1:2, 1:2]
frame.iloc[[0,2], [1,2]]
- 使用条件来选择:
frame[frame.year>2001]
,选择year列中大于2001的数据
frame[frame>2001]
,选择frame中所有大于2001的数据
frame[frame[‘year'].isin([‘2000',‘2002'])]
,选择year列的值为’2000’,'2002’的所有行
🕤 2.3.14 相关操作
- 统计数据:
a.mean()
,对a的每一列数据值求平均值;
a.mean(1)
,对a的每一行数据值求平均值
a[‘x'].value_counts()
,统计列x中各值出现的次数 - 对数据应用函数:
a.apply( lambda x : x.max() - x.min() )
,对a的每一列,返回最大值和最小值的差 - 字符串操作:
a[‘gender1'].str.lower()
,将gender1中所有的英文转化为小写,注意Dataframe没有str属性,只有Series有,所以要选取a中的gender1列。
🕤 2.3.15 读取与写入文件
- 写入.csv文件:
frame3.to_csv(‘C:\Users\Hans\frame3.csv’) - 读取.csv文件:
frame4 = pd.read_csv(‘C:\Users\Hans\frame3.csv’)
frame4 = pd.read_csv(‘C:\Users\Hans\frame3.csv’, index_col=0)
OK,以上就是本期知识点“Python语法与库的简介”的知识啦~~ ,感谢友友们的阅读。后续还会继续更新,欢迎持续关注哟📌~
💫如果有错误❌,欢迎批评指正呀👀~让我们一起相互进步🚀
🎉如果觉得收获满满,可以点点赞👍支持一下哟~