python基础

基本语法

注释

单行:#

多行:'''"""

1
2
3
4
# 如果一段代码太长,可用\分段
a = b + c + \
d + e + \
f

变量类型

查看类型

type()查看变量类型

isinstance(a, (类型1, ...))判断是否是其中一种类型或子类

数字

  • int
  • bool(True/False)
  • float
  • complex(复数)

/返回浮点数,//返回整数的部分

字符串

单行字符串可用''"",多行字符串可用''' '''""" """

转义符号\

不让\生效,在引号前加r

可用+连接字符串,*重复字符串

字符串是不可改变量

切片

左闭右开

-1为末尾位置

还可加上步长,步长-1表示逆向

格式化

1
2
3
4
5
6
7
8
print ("我叫 %s 今年 %d 岁!" % ('小明', 10))

# 还有前面加f的格式化语法
name = 'aaa'
print(f'Hello {name}') # Hello aaa

w = {'name': 'baidu', 'url': 'www.baidu.com'}
print(f'{w["name"]}: {w["url"]}') # baidu: www.baidu.com

列表

列表的元素是可改变的

1
2
3
4
5
6
a = [1, 2, 3, 4, 5, 6]
print(a[1 : 2]) # [2]
print(a[1 :]) # [2, 3, 4, 5, 6]

a[1] = 0
print(a) #[1, 0, 3, 4, 5, 6]

列表操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 增加元素
list1 = [1, 2, 3]
list1.append(4)
print(list1) # [1, 2, 3, 4]

# 删除元素
del list1[0]
print(list1) # [2, 3, 4]

# 比较列表
import operator

list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(operator.eq(list1, list2)) # False

元组

元组的元素不可以改变

可以把字符串看成特殊的元组

1
2
3
4
5
tup = (1, ) # 只包含一个元素的元组
a = (1) # int类型
b = () # 空元组
print(type(tup)) # <class 'tuple'>
print(type(a)) # <class 'int'>

集合

集合的元素可变,唯一

创建可用{}set(),空集合要用set

1
2
3
4
5
6
7
8
9
10
11
12
a = set('abracadabra')
b = set('alacazam')

print(a)

print(a - b) # a 和 b 的差集

print(a | b) # a 和 b 的并集

print(a & b) # a 和 b 的交集

print(a ^ b) # a 和 b 中不同时存在的元素

字典

创建可用{}dict,空字典可用{}创建

key必须为不可变类型(数字、字符串、元组、布尔等)

1
2
3
4
a = {'a': 1, 'b': 2, 'c': 3, 4 : 'd'}
print(a) # {'a': 1, 'b': 2, 'c': 3, 4: 'd'}
print(a['a']) # 1
print(a[4]) # d

字典操作

1
2
3
4
5
6
7
8
# 删除指定key
d = {1 : 1, 2 : 2, 3 : 3}
del d[1]
print(d) # {2: 2, 3: 3}

# 清空字典
d.clear()
print(d) # {}

输入输出

1
2
3
4
5
6
# 输入
price = input("Enter price: ")

# print默认带换行
print(price)
print(price, end = '')

format格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 按位置填充
print("Hello, {}!".format("Alice"))
print("Hello, {0}, you are {1} years old.".format("Bob", 25))

# 按关键字填充
print("Site name: {name}, Rank: {rank}".format(name="Google", rank=1))

# 混合字典访问
user = {"name": "Alice", "age": 18}
print("Name: {0[name]}, Age: {0[age]}".format(user))

# 解包
data = {"site": "Google", "rank": 1}
print("Site: {site}, Rank: {rank}".format(**data))

格式化控制符

格式符 含义 示例值 示例结果
d 十进制整数 {0:d} 42
f 浮点数(默认 6 位) {0:f} 3.141593
.2f 保留 2 位小数 {0:.2f} 3.14
>10 右对齐,占 10 宽度 {0:>10} text
<10 左对齐,占 10 宽度 {0:<10} text
^10 居中,占 10 宽度 {0:^10} text
, 千位分隔符 {0:,} 1,000,000
% 百分比(乘以 100) {0:.2%} 25.00%

条件/循环

  • if / elif / else

  • match…case(相当于switch…case,在3.10版本可用)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    status = 400
    match status:
    case 400 | 401 | 402:
    return "Bad request"
    case 404:
    return "Not found"
    case 418:
    return "I'm a teapot"
    case _:
    return "Something's wrong with the internet"
  • while…else

  • for…in…else

    range(5): 遍历从0到4

  • pass: 空语句,不做任何事

导入模块

导入模块的搜索路径:

  1. 当前目录
  2. 环境变量 PYTHONPATH 指定的目录
  3. Python 标准库目录
  4. .pth 文件中指定的目录
1
2
3
4
5
6
7
8
# 整个模块
import sys

# 模块中的某个函数
from sys import argv, path

# 模块中的所有函数(不推荐,容易覆盖已经定义的函数)
from sys import *

每个模块都有一个__name__属性

  • 如果模块是被直接运行,__name__ 的值为 __main__
  • 如果模块是被导入的,__name__ 的值为模块名。

数学函数

  • abs(): 绝对值
  • ceil()/floor(): 向上/向下取整
  • round(): 四舍五入
  • cmp(): 比较两个数
  • max()/min(): 取最大/最小值
  • pow(): 开方
  • sqrt(): 平方根

错误异常

处理异常

1
2
3
4
5
6
7
8
9
10
11
# 完整语法
try:
# 可能抛出异常的代码
except ExceptionType1:
# 处理方式 1
except ExceptionType2 as e:
# 处理方式 2,可获取异常对象 e
else:
# 没有发生任何异常时执行
finally:
# 不管是否异常都会执行(清理资源用)

抛出异常

1
2
3
4
def sqrt(x):
if x < 0:
raise ValueError("不能对负数开平方")
return x ** 0.5

常见异常类型

异常名 说明
ValueError 参数类型/值不合法
ZeroDivisionError 除以 0
IndexError 索引超出范围
KeyError 字典中键不存在
FileNotFoundError 打开的文件不存在
TypeError 操作/函数类型不对
NameError 使用了未定义的变量

自定义异常

1
2
3
4
5
6
7
8
9
10
class MyError(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return self.message

try:
raise MyError("MyError")
except MyError as e:
print(e)

文件

打开文件

1
f = open(file, mode='r', encoding=None)

打开模式

模式 含义 文件不存在时行为 可读 可写 是否清空原文件
r 只读 ❌ 报错
w 只写 ✅ 创建新文件 ✅ 清空
a 追加写入 ✅ 创建新文件 ❌(在末尾写)
r+ 读写 ❌ 报错
w+ 写读(先清空) ✅ 创建新文件 ✅ 清空
a+ 读写(追加写入) ✅ 创建新文件 ❌(只追加)
rb/wb 二进制读写 适合图片、音频等 看上面 看上面 看上面

写入文件

使用with open() as f会自动关闭文件,不然要手动f.close()

1
2
3
4
5
6
7
8
# 覆盖写入
with open("test.txt", "w", encoding="utf-8") as f:
f.write("Hello, world!\n")
f.write("Second line.\n")

# 追加写入
with open("test.txt", "a", encoding="utf-8") as f:
f.write("Appended line.\n")

读取文件

1
2
3
4
5
6
7
8
9
10
11
12
13
# 一次读完全部内容(字符串)
with open("test.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)

# 按行读取
with open("test.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
for line in lines:
print(line.strip())

# 读一行
f.readline()

迭代器

访问集合元素的一种方式

可以记住遍历的位置的对象,只能往前不会后退

使用

1
2
3
4
5
6
7
8
9
10
11
# 用next()访问
a = [1, 2, 3]
b = iter(a)
print(next(b)) # 1
print(next(b)) # 2
print(next(b)) # 3
print(next(b)) # 报错

# 用for循环访问
for i in iter(a):
print(i)

创建迭代器

实现__iter__()__next__()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MyNum:
def __iter__(self):
self.num = 0
return self

def __next__(self):
tmp = self.num
if tmp < 20:
self.num += 1
return tmp
else:
raise StopIteration # 停止迭代
myclass = MyNum()
it = iter(myclass)
for i in it:
print(i)

生成器

使用了yield函数被称为生成器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 每次到yield时,函数会返回n,并且在这里暂停,在下次调用时从这里继续执行
def countdown(n):
while n > 0:
yield n
n -= 1

# 创建生成器对象
generator = countdown(5)

# 通过迭代生成器获取值
print(next(generator)) # 输出: 5
print(next(generator)) # 输出: 4
print(next(generator)) # 输出: 3

# 使用 for 循环迭代生成器
for value in generator:
print(value) # 输出: 2 1

函数

不定长参数

1
2
3
4
5
6
7
# 一个*为元组
def method(var1, *var2):
print(var1, " ",var2)

method(1) # 1 ()
method(1, 2) # 1 (2,)
method(1, 2, 3) # 1 (2, 3)
1
2
3
4
5
6
7
8
9
10
11
12
# 一个**为字典
def method(var1, *var2, **var3):
print(var1)
print(var2)
print(var3)

method(1,2,3,4,5, a = 1, b = 2)
'''
1
(2, 3, 4, 5)
{'a': 1, 'b': 2}
'''

匿名函数

作用是为了简洁,性能上和普通函数没差

1
2
3
4
5
sum = lambda arg1, arg2: arg1 + arg2

# 调用sum函数
print("相加后的值为 : ", sum(10, 20)) # 相加后的值为 : 30
print("相加后的值为 : ", sum(20, 20)) # 相加后的值为 : 40

函数装饰器

函数装饰器是一种函数,它接受一个函数作为参数,并返回一个新的函数或修改原来的函数

用于不修改原函数的基础上动态地增加或修改函数的功能

类似java的注解+AOP

基本语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def decorator_function(original_function):
def wrapper(*args, **kwargs):
# 这里是在调用原始函数前添加的新功能
before_call_code()

result = original_function(*args, **kwargs)

# 这里是在调用原始函数后添加的新功能
after_call_code()

return result
return wrapper

# 使用装饰器
@decorator_function
def target_function(arg1, arg2):
pass # 原始函数的实现

实例:函数执行时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import time


def time_logger(func):
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("参数: ", args)
print("执行时间: ", end_time - start_time)
return res
return wrapper


@time_logger
def say_hello(name):
print("Hello! ", name)
time.sleep(0.5)

say_hello("Alice")

实例:带参数的装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for i in range(n):
func(*args, **kwargs)
return wrapper
return decorator

@repeat(3)
def say_hello():
print("Hello World!")

say_hello()

类装饰器

类装饰器用于动态修改类行为

实例:实现类的单例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class SingletonDecorator:
"""类装饰器,使目标类变成单例模式"""
def __init__(self, cls):
self.cls = cls
self.instance = None

def __call__(self, *args, **kwargs):
"""拦截实例化过程,确保只创建一个实例"""
if self.instance is None:
self.instance = self.cls(*args, **kwargs)
return self.instance

@SingletonDecorator
class Database:
def __init__(self):
print("Database 初始化")

db1 = Database()
db2 = Database()
print(db1 is db2) # True,说明是同一个实例

面向对象

构造方法

__init()__,创建对象时自动调用

不写默认是个空的构造方法

1
2
3
4
5
6
7
8
class Person:
def __init__(self, name, age):
self.name = name
self.age = age

p = Person("John", 22)
print(p.age)
print(p.name)

类方法

类方法用def定义,且第一个参数要为self

继承

子类继承父类的属性和方法

子类里可用super().来调用父类的方法

1
2
3
4
5
6
7
8
9
10
11
class Animal:
def speak(self):
print("动物在叫")

class Dog(Animal):
def bark(self):
print("汪汪汪")

d = Dog()
d.speak()
d.bark()

多继承时决定调用哪个类的方法,按从左到右的优先级

即先找自己,在从左到右找父类(如果父类也有父类,则会顺着它的父类找上去)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A:
def hello(self):
print("A")

class B(A):
def hello(self):
print("B")

class C(A):
def hello(self):
print("C")

class D(B, C):
pass

D().hello() # 输出 B

私有属性和方法

定义:在属性或方法前加__

私有属性和方法只能在本类中访问

python的私有并不是真的私有,只是改了其名字,变为_类型__属性名

1
2
3
4
5
6
7
8
9
10
11
12
13
class Person:
def __init__(self, name, age):
self.__name = name # 私有属性
self.__age = age # 私有属性

def __say_secret(self): # 私有方法
print("这是一个秘密")

def show(self):
print(f"{self.__name}, {self.__age}")
self.__say_secret()

print(Person("Tom", 20).show())

魔法方法

魔法方法是 Python 自动调用的一些特殊方法

方法 作用
__init__(self, ...) 构造函数,创建对象时调用
__new__(cls, ...) 真正创建对象的方法,__init__ 前执行(用于元类)
__del__(self) 析构函数,删除对象时调用
__str__() print(obj) 时调用
__repr__() 解释器或 repr(obj) 时调用

运算符重载

方法 对应操作
__add__ + 加法
__sub__ - 减法
__mul__ * 乘法
__eq__ == 比较
__lt__ < 小于

多线程

Python的多线程是并发的,而非真正的并行

CPython使用全局解释器锁(GIL)来保证线程安全,即同一时刻只有一个线程可以执行Python字节码。即使有多核CPU,GIL也会阻止多线程的并行执行

通过threading模块来使用多线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import threading
import time

def say_hello():
for i in range(3):
print(f"线程 {threading.current_thread().name} 打招呼")
time.sleep(1)

# 创建两个线程
t1 = threading.Thread(target=say_hello, name='T1')
t2 = threading.Thread(target=say_hello, name='T2')

t1.start()
t2.start()

t1.join()
t2.join()

print("主线程结束")
功能 说明
Thread(target=...) 创建线程并指定要执行的函数
start() 启动线程
join() 阻塞,直到被调用线程终止
current_thread() 获取当前线程信息
Lock() 创建互斥锁,防止多线程同时修改共享数据
enumerate() 返回一个包含正在运行的线程的列表
active_count() 返回正在运行的线程数量

守护线程

主线程会等待普通线程结束后才结束,而不会等待守护线程

要在start()前设置t.daemon = True才为守护线程

适合做后台服务或辅助任务

线程同步

互斥锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import threading

count = 0
lock = threading.Lock()

def add():
global count
for _ in range(100000):
with lock:
count += 1 # 保证这段代码只有一个线程能执行

t1 = threading.Thread(target=add)
t2 = threading.Thread(target=add)
t1.start()
t2.start()
t1.join()
t2.join()

print("count:", count)

可重入锁

threading.RLock()

支持一个线程加多次锁,适合递归或多个函数都加锁时

信号量

1
2
3
4
5
6
7
8
9
import threading
import time

sem = threading.Semaphore(3) # 最多3个线程同时进入

def task():
with sem:
print(threading.current_thread().name, "进入")
time.sleep(2)

线程通知

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import threading
import time

event = threading.Event()

def worker():
print("等待事件触发...")
event.wait()
print("事件已触发,开始工作")

t = threading.Thread(target=worker)
t.start()

time.sleep(3)
print("触发事件!")
event.set()

JSON

通过dump()转换为json格式,load()读取json

1
2
3
4
5
6
7
8
9
10
11
import json

# 写入文件
data = {'name': 'Bob', 'age': 30, 'is_student': True}
with open('data.json', 'w') as f:
json.dump(data, f, indent=4, ensure_ascii=False)

# 读出json数据
with open('data.json', 'r') as f:
data = json.load(f)
print(data)

Numpy

NumPy 是一个用于处理数组的 Python 库。

创建数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import numpy as np

# 创建整型数组
ar1 = np.array([1, 2, 3])
print(ar1) # [1 2 3]

# 创建浮点型数组
ar2 = np.array([1.0, 2, 3])
print(ar2) # [1. 2. 3.]

# 创建一个都是1的数组
arr1 = np.ones((3, 3)) # 3行3列
print(arr1)
print(arr1.shape) # 查看数组的维数
print(arr1.reshape((1, -1))) # 重塑数组的维度,填-1会自己计算,这里会变为1行6列
print(arr1.reshape(-1)) #变为1行6列

# 创建全0数组(np.zeros(), 同上)

# 创建递增数组
arr1 = np.arange(1, 10)
print(arr1) # [1 2 3 4 5 6 7 8 9]

# 创建随机数组
arr1 = np.random.random(3)
print(arr1)

# 创建服从(0, 1)正态分布的数组
arr1 = np.random.normal(0, 1, 100)
print(arr1)

访问数组

1
2
3
4
5
6
7
arr1 = np.array( [[1, 2, 3], [4, 5, 6]])

# 访问二维数组,注意一个中括号
print(arr1[0, 1])

# 花哨索引, 第一个中括号为行,第二个为列
print(arr1[ [0, 1], [1, 2] ]) # [2 6]

数组操作

切片

numpy的切片仅是原数组的视图,原python的是拷贝。要拷贝用数组.copy()

1
2
3
4
5
6
7
8
9
10
# 二维切片
arr1 = np.arange(1, 21).reshape(4, 5)
# [[ 1 2 3 4 5]
# [ 6 7 8 9 10]
# [11 12 13 14 15]
# [16 17 18 19 20]]
print(arr1)
# [[ 7 8 9]
# [12 13 14]]
print(arr1[1:3, 1:-1])

翻转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np

# 向量翻转
arr1 = np.arange(10)
arr1 = np.flipud(arr1)
print(arr1) # [9 8 7 6 5 4 3 2 1 0]

# 矩阵翻转
arr1 = np.arange(1, 21).reshape(4, 5)
arr1 = np.fliplr(arr1)
# 左右翻转
print(arr1)
# 上下翻转
arr1 = np.flipud(arr1)
print(arr1)

转置

1
2
# 转置数组
arr2 = arr1.T

重塑

1
2
# 重塑为3行4列
arr2 = arr1.reshape((3, 4))

拼接

1
2
3
4
5
6
7
8
9
10
# 向量拼接
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
print(np.concatenate((arr1, arr2))) #[1 2 3 4 5 6]

# 矩阵拼接
# 注意维数要一样,concatenate有个默认参数axis=0表示竖着拼接,改为1为横着拼
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[7, 8, 9]])
print(np.concatenate((arr1, arr2)))

截断

1
2
3
4
5
6
7
8
9
10
11
# 向量的截断
arr1 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
print(np.split(arr1, (2, 4))) # [array([1, 2]), array([3, 4]), array([5, 6, 7, 8, 9])]

# 矩阵的截断
arr1 = np.arange(8).reshape(2, -1)
print(np.split(arr1, (1, ), axis=1))
# [array([[0],
# [4]]),
# array([[1, 2, 3],
# [5, 6, 7]])]

矩阵运算

相乘

1
2
3
4
5
6
7
8
9
10
# 向量相乘
arr1 = np.arange(5)
arr2 = np.arange(5)

print(np.dot(arr1, arr2))

# 矩阵相乘
arr1 = np.arange(5)
arr2 = np.arange(15).reshape(5, 3)
print(np.dot(arr1, arr2))

数学函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 绝对值
arr1 = np.array((-10, 0, 10))
print(np.abs(arr1))

# 三角函数
np.sin(arr1)
np.cos(arr1)
np.tan(arr1)

# 指数函数
np.exp() # 以e为底
print("2^x = ", 2 ** arr1)

# 对数函数
np.log(arr1)
print("log2(x) = ", np.log(arr1) / np.log(2))

# 最大值, axis=0为列之间比较
arr1 = np.array(((2, 4, 6), (1, 2, 3)))
print(np.max(arr1, axis=0)) # [2 4 6]
# 最小值np.min()、求和np.sum()、均值函数mean()、标准差np.std()同理
# 在函数前加上nan可以忽略缺失值,如np.nanmin()

布尔

1
2
3
4
5
6
7
8
9
10
11
12
# any: 全部或,all: 全部于
arr1 = np.array((False, False, True))
print(np.any(arr1)) # True
print(np.all(arr1)) # False

# 返回满足条件的元素
arr1 = np.array((1, 2, 3))
print(arr1[ arr1 > 1 ]) # [2 3]

# 查找符合条件的元素的下标
arr1 = np.array((1, 2, 3))
print(np.where(arr1 > 1)) # (array([1, 2], dtype=int64),)

Pandas

Pandas 提供了易于使用的数据结构和数据分析工具,特别适用于处理结构化数据,如表格型数据。可以看做是numpy的扩展

创建数据结构

Series

和字典有点像,但这个是有序的,且key可重复

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd

# 通过字典创建
dict_v = {'a': 0, 'b': 0.25, 'c': 0.75, 'd': 1}
sr = pd.Series(dict_v)
print(sr)

# 通过数组创建(元组、列表、张量、向量都行)
# 如果没传入key, 默认0、1、2 ...
k = ['a', 'b', 'c', 'd']
v = [0, 0.25, 0.75, 1]

sr = pd.Series(data=v, index=k)
print(sr)

DataFrame

类似二维表格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
v1 = [53, 64, 72, 82]
v2 = ['女', '男', '女', '男']
i = ['1号', '2号', '3号', '4号']

# 通过数组创建
# 如果key不一样,会在空的地方用NaN填充
sr1 = pd.Series(v1, index=i)
i[3] = '6号'
sr2 = pd.Series(v2, index=i)
df = pd.DataFrame({'年龄': sr1, '性别': sr2})
print(df)
# 年龄 性别
# 1号 53.0 女
# 2号 64.0 男
# 3号 72.0 女
# 4号 82.0 NaN
# 6号 NaN 男

# 通过矩阵创建
v = np.array([ [53, '女'], [64, '男'], [72, '女'], [82, '男'] ])
i = ['1号', '2号', '3号', '4号']
c = ['年龄', '性别']
df = pd.DataFrame(v, index=i, columns=c)
print(df)

访问

Series

如果key是数字的话,会和下标混淆,所有可以用loc显示索引(key),iloc隐式索引(下标)

1
2
3
4
5
6
7
8
9
10
11
k = ['a', 'b', 'c', 'd']
v = [0, 0.25, 0.75, 1]
sr = pd.Series(data=v, index=k)

# 通过key访问
print(sr['c'])
print(sr.loc['c'])

# 访问切片,显示索引注意是左闭右闭,隐式是左闭右开
print(sr['a':'c'])
print(sr[0:2])

DataFrame

必须使用索引器

1
2
3
4
5
6
7
8
9
10
11
12
v = np.array([ [53, '女'], [64, '男'], [72, '女'], [82, '男'] ])
i = ['1号', '2号', '3号', '4号']
c = ['年龄', '性别']
df = pd.DataFrame(v, index=i, columns=c)

# 隐式索引访问
print(df.iloc[0][0])
# 显式索引访问
print(df.loc['1号']['年龄'])

# 访问切片
print(df.loc['1号':'3号', '年龄'])

对象变形

转置

1
2
3
4
5
6
7
v = [[53, 64, 72, 82], ['女', '男', '女', '男']]
i = ['年龄', '性别']
c = ['1号', '2号', '3号', '4号']

df = pd.DataFrame(v, index=i, columns=c)

print(df.T)

翻转

1
2
3
4
# 上下翻转
print(df.T.iloc[: : -1, :])
# 左右翻转
print(df.T.iloc[:, : : -1])

重塑

1
2
3
4
5
6
7
8
9
10
11
12
i = ['1号', '2号', '3号', '4号']
v1 = [10, 20, 30, 40]
v2 = ['女', '男', '女', '男']
v3 = [1, 2, 3, 4]

sr1 = pd.Series(v1, index=i)
sr2 = pd.Series(v2, index=i)
sr3 = pd.Series(v3, index=i)

df = pd.DataFrame({'年龄': sr1, '性别': sr2})
df['拍照'] = sr3
print(df)

合并

1
2
3
4
# 合并行(默认)
pd.concat({sr1, sr2}, axis = 0)
# 合并列
pd.concat({sr1, sr2}, axis = 1)

缺失值

找缺失值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import pandas as pd

# Series找缺失值
k = [1, 2, 3, 4]
v = [1, 2, 3, None]

sr = pd.Series(v, index=k)
print(sr.isnull())
# 1 False
# 2 False
# 3 False
# 4 True
# dtype: bool

# DataFrame找缺失值
v = [ [None, 1], [64, None], [72, 3], [82, 1]]
i = [ '1号', '2号', '3号', '4号']
c = [ '年龄', '牌照']

df = pd.DataFrame(v, index=i, columns=c)
print(df.isnull())
# 年龄 牌照
# 1号 True False
# 2号 False True
# 3号 False False
# 4号 False False

剔除缺失值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Series剔除缺失值
k = [1, 2, 3, 4]
v = [1, 2, 3, None]

sr = pd.Series(v, index=k)
print(sr.dropna())
# 1 1.0
# 2 2.0
# 3 3.0

# DataFrame剔除缺失值
v = [ [None, 1], [64, None], [72, 3], [82, 1]]
i = [ '1号', '2号', '3号', '4号']
c = [ '年龄', '牌照']

df = pd.DataFrame(v, index=i, columns=c)
print(df.dropna()) # 剔除有None的行
print(df.dropna(how='all')) # 整行是None时才剔除

填充缺失值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Series填充缺失值
k = [1, 2, 3, 4]
v = [1, 2, 3, None]

sr = pd.Series(v, index=k)
print(sr.fillna(0))

# DataFrame填充缺失值
v = [ [None, 1], [64, None], [72, 3], [82, 1]]
i = [ '1号', '2号', '3号', '4号']
c = [ '年龄', '牌照']

df = pd.DataFrame(v, index=i, columns=c)
print(df.fillna(0))

Excel

导入Excel

1
2
3
4
5
import pandas as pd

# 要先将xlsx另存为csv文件
# index_col=0: 把第0行作为行索引,而不是数据
df = pd.read_csv('test.csv', index_col=0, encoding='gbk')

读取数据

1
2
3
4
5
6
7
8
9
# 读取前5行
print(df.head())

df.max() # 每列最大值
df.min() # 最小值
df.mean() # 平均值
df.std() # 标准差
df.sum() # 求和
df.describe() # 查看所有聚合函数的结果

数据透视

1
2
3
4
5
6
7
8
9
10
11
# 按列名2分类,算出均值(默认)
df.pivot_table(列名1, index=列名2)

# 按列名2分类,再按列名3分类,算出均值
df.pivot_table(列名1, index=列名2, columns=列名3)

# 重置列的值,改为范围
pd.cut( df['年龄'], [0, 25, 125])

# 重置列的值,自动分割, 2为自动分为两列
pd.qcut( df['费用'], 2 )

python基础
http://xwww12.github.io/2025/06/01/python/python基础/
作者
xw
发布于
2025年6月1日
许可协议