python 各种“集合”类型的操作

前言

编程中,经常需要处理一堆数据,为了操作一堆数据 ,提供了几个基本的类型:set,tuple,list,dict, 以及常用的两个库numpy,pandas。在使用时,可能会迷糊,什么时候该用什么类型。本文是对这些知识的梳理。
对每一个类型,我们关注点都是 CRUD 操作,以及访问方法。

set 集合

set 与数学中的集合概念完全一样,由不重复元素组成。对于集合,我们关心的是集合中有什么元素 ,不关心次序,所以集合中没有按下标的访问方法。
set 支持并集,差集,交集的操作。
注意的是,所有set 中的元素必须是hashable类型,如何hashable 就不在此展开。

s1={1,23} # 创建
s1.remove(3) # 删除元素
s1.add(3) # 添加元素
s1.clear() # 清空
s1.add([1,2,3]) # 批量添加元素
s2={2,3,4} 
s1.copy() # 复制

for x in s1:  #访问所有元素
  print(x)

s1 | s2 # {1,2,3,4} 并集
s1.union(s2) # 等于 s1 | s2
s1 & s2 # {2,3} 交集
s1.intersection(s2) # 相当于 s1 & s2  
s1 ^ s2 # {1,4} 去除相同的元素,也就是交集的补集
s1.symmetric_difference(s2) # 等于 s1 ^ s2
s1-s2 # {1} 去除存在于s2中的元素
s2-s1 # {4} 去除存在于s1中的元素
s1.difference(s2) # 相当于 s1-s2 ,该操作不影响s1

# 以下带update的方法会修改原集合
s1.intersection_update(s2) # 相当于 s1 & s2  
s1.difference_update_update(s2) # s1变成了{1}, 该操作影响s1
s1.symmetric_difference_update(s2)

s1={1}
s2={1,2}
1 in s1 # True 判断元素是否存在
s1<s2 # True ,s1属于s2
s1.issubset(s2) # 等于 s1<s2
s2>s1 # True, s2 包含 s1
s2.ssuperset(s1) # 等于 s2>s1

list 列表,数组

如果我们要记录一组按顺序的数据,比如每天的跑步公里数,按天形成了一个列表,就用list 。list 与set 的不同在于:

  1. list 可以按下标访问
  2. list 中元素可重复
  3. list 中元素可以是任何值
    list 中的每个元素,相当于多了一个属性:顺序。 所以,list 中很多操作是和顺序相关,比如 reverse, sort, index,insert,append . 为了方便的访问元素,list 还提供了切片操作,这一点是特色。
# 创建
l = ['a','b','c'] 
l.copy()
l+l #  ['a','b','c','a','b','c'] 支持加法,不支持减法
dl = l*3 # 相当于 l+l+l 

#添加元素的操作,包括 append, insert
l.append('d')
l.extend(['e'.'f']) # 批量添加
l.insert('z',0)  # 指定位置插入
#删除元素,包括remove ,pop ,del
l.remove('a') # 删除指定的元素,如果有多个,删除第一个
l.pop() # 删除最后一个
l.pop([1,2]) #删除指定位置的元素
del l[1] # 删除指定位置元素
#更新
l[0]='hello'
#获取,按下标获取,以及按切片获取一个新的list
l[0] # 第0个 ,list的下标是从0开始。
l[-1] # 最后一个
l[:] # 所有元素
l[1:] # 从下标
l[:2] # 从下标0至下标2,不包括2
l[1:3] # 从下标1到下标2,不包括3

tuple 元组

元组相当于不可变的list ,也就是创建后不能改变,其它操作与list 一样

t=(1,2)
t[0]=5 # 这是不允许的

dict 字典

如果我们希望给每个数据给一个名称,那就是字典:dict 。dict 保存的是 key,value 对。字典里的key不能重复,访问value 用key做下标 。

d = {"a":1,"b":2}
d['a']  #用下标访问
for key in d:  # 访问所有元素
  print(d[key])  
  
d['a']=3 # 修改

del d['a'] # 删除

deque

collections.deque 提供了先进先出的操作,比list 多了一个 popleft() 方法

numpy

list 不具备科学计算能力,比如矩阵运算,数学统计。numpy 则提供了多维数组,及相应的统计,矩阵运算等,还支持复数操作,这些运算包括点乘,数乘,矩阵乘法,转置。从一个矩阵中切片 ,也相当方便。

数乘,点乘,与矩阵乘法

注意:矩阵乘法符号是@

from numpy import array
A=array([1,2]) # 创建一维数组
A*2 # 数乘
Out[4]: array([2, 4])
A*A # 点乘
Out[5]: array([1, 4])
A*A.T # 一维数组转置后还是一维数组
Out[6]: array([1, 4])
A@A.T # 一维数组转置后还是一维数组
Out[7]: 5
A.T@A # 一维数组转置后还是一维数组,所以矩阵乘法等同于点乘
Out[8]: 5
a=array([[1,2]]) # 创建二维数组
a.T@a # 矩阵乘法
Out[10]: 
array([[1, 2],
       [2, 4]])
A*a
Out[11]: array([[1, 4]])
A*a.T
Out[12]: 
array([[1, 2],
       [2, 4]])

聚合运算与AXIS 轴

如果需要按行,或者按列做聚合运算( 比如求和,求平均,求最大值, 求标准差),需要明白axis 的概念。x 轴(行)就是0,y轴(列)就是1

from numpy import array, max
m=array(
	[[1,2,3],
	 [4,5,6],
	 [7,8,9]
	])
m.sum() # 45, 不指定轴,所有元素相加
m.sum(axis=0) # 按行相加
Out[7]: array([12, 15, 18])
m.sum(axis=1) # 按列相加
Out[6]: array([ 6, 15, 24])
max(m,axis=1)
Out[20]: array([3, 6, 9])

叠代与切片

叠代可以按所有元素,或者按行,或列
切片的写法是 [开始:结束:步长]

m=array(
	[[1,2,3],
	 [4,5,6],
	 [7,8,9]
	])
m[1:3,1:3] # 取第2行到第3行,第2列到第3列 
Out[28]: 
array([[5, 6],
       [8, 9]])
a = array([1,2,3,4,5,6])
a[0:6:2] # 步长 2
Out[26]: array([1, 3, 5])

矩阵运算

包括 dot,cross,outer,vdot,svg 等 ,可参看numpy 文档

pandas

如果我们想给每一行,或者每一列给一个名字的话,那么numpy 就不行了,得用pandas。pandas 提供两个基本的类:

  1. Series 一维的带标签的数组
  2. DataFrame 二维的,每行或每列都带标签 ,相当于excel中的表格
  3. Index 用来做索引
    除此外,pandas 还能直接绘图

Series

from pandas import Series
s = Series([1,3,7,12]) 
s = Series([1,3,7,12,16],index=['a','b','c','d','e'])
#用数字切片
s[0] 
s[0:3]] # 选出几个
s[[0,1,4]] # 任意选择
#用标签切片
s['a']
s[['a','e']]
s['a':'c']
s.describe() # 统计
Out[62]: 
count     5.000000
mean      7.800000
std       6.220932
min       1.000000
25%       3.000000
50%       7.000000
75%      12.000000
max      16.000000
dtype: float64
s.plot() # 绘图

DataFrame

from pandas import DataFrame
trades={
  'close':[1.2,1.11,1.16,1.13,1.09],
  'open':[1.18,1.21,1.11,1.15,1.13],
  'high':[1.22,1.24,1.18,1.17,1.15],
  'low':[1.15,1.08,1.09,1.07,1.08]
}
dates=['2010-01-01','2010-01-02','2010-01-03','2010-01-04','2010-01-05']
pd= DataFrame(trades,index=dates) # 创建,给出数据,指明第行的标签。另外,pandas还支持从csv,excel格式的数据
pd
Out[9]: 
            close  open  high   low
2010-01-01   1.20  1.18  1.22  1.15
2010-01-02   1.11  1.21  1.24  1.08
2010-01-03   1.16  1.11  1.18  1.09
2010-01-04   1.13  1.15  1.17  1.07
2010-01-05   1.09  1.13  1.15  1.08

pd['close']  # 按列名访问列
Out[10]: 
2010-01-01    1.20
2010-01-02    1.11
2010-01-03    1.16
2010-01-04    1.13
2010-01-05    1.09
Name: close, dtype: float64

pd[['close','open']] #同时取两列
Out[16]: 
            close  open
2010-01-01   1.20  1.18
2010-01-02   1.11  1.21
2010-01-03   1.16  1.11
2010-01-04   1.13  1.15
2010-01-05   1.09  1.13

pd.iloc[0] # 按行下标,访问一行
Out[24]: 
close    1.20
open     1.18
high     1.22
low      1.15
Name: 2010-01-01, dtype: float64

pd.loc['2010-01-01'] # 按标签,访问一行
Out[25]: 
close    1.20
open     1.18
high     1.22
low      1.15
Name: 2010-01-01, dtype: float64

pd.loc['2010-01-01':'2010-01-03'] # 按标签切片
Out[29]: 
            close  open  high   low
2010-01-01   1.20  1.18  1.22  1.15
2010-01-02   1.11  1.21  1.24  1.08
2010-01-03   1.16  1.11  1.18  1.09

pd.describe() # 统计
Out[31]: 
          close      open      high       low
count  5.000000  5.000000  5.000000  5.000000
mean   1.138000  1.156000  1.192000  1.094000
std    0.043243  0.039749  0.037014  0.032094
min    1.090000  1.110000  1.150000  1.070000
25%    1.110000  1.130000  1.170000  1.080000
50%    1.130000  1.150000  1.180000  1.080000
75%    1.160000  1.180000  1.220000  1.090000
max    1.200000  1.210000  1.240000  1.150000

pd.keys() # 所有列名称
Out[32]: Index(['close', 'open', 'high', 'low'], dtype='object')
pd.index # 得到索引 
Out[33]: Index(['2010-01-01', '2010-01-02', '2010-01-03', '2010-01-04', '2010-01-05'], dtype='object')
pd.plot()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值