Python 和 SPL 对比 2——集合
序列是被排成一列的对象(或事件),这样每个元素不是在其他元素之前,就是在其他元素之后,元素之间的顺序非常重要。
集合是具有某种特定性质的具体的或抽象的对象汇总而成的集体。构成集合的这些对象则称为该集合的元素,其中无重复元素,元素间的顺序也不重要。
以上是序列和集合在数学上的定义,他们在 Python 和esProc SPL(以后无具体说明简称 SPL)中是什么样子呢?
Python
简单集合
集合介绍
Python中原生的序列是一种称为列表(list)的数据结构,形式如 [1,2,3,4]。它符合序列的基本定义,元素顺序很重要而且允许重复元素。
Python的 numpy 库中的序列是一种称为数组(array)的数据结构,形式如 [1 2 3 4]。它也符合序列的基本定义,元素顺序很重要而且允许重复元素,但不支持不同类型的元素。
Python的 Pandas 库中的序列是一种称为系列(Series)的数据结构,形式如。它也符合序列的基本定义,元素顺序很重要而且允许重复元素,只不过 Series 自带了索引。
Python中原生的集合是一种称为集合(set)的数据结构,形式如 {1, 2, 3, 4}。它符合集合的基本定义,顺序不重要且无重复元素。
光是常用的集合数据结构就有四种,虽然他们之间可以相互转换,但成本相对也比较高,语法也是一大堆。
基本操作
增删改查是集合的基本操作,是必须要掌握的,可是四种数据结构的语法又完全不同,我们以增加元素为例介绍。
数据结构 |
例子 |
代码 |
解释 |
结果 |
list |
l=[1,2,3,4] |
l.append(5) |
末位增加 |
[1,2,3,4,5] |
l.insert(2,5) |
指定位置增加 |
[1,2,5,3,4] |
||
array |
a=[1 2 3 4] |
np.hstack((a,[5])) |
横向增加 |
[1 2 3 4 5] |
np.vstack((a,[5,6,7,8])) |
纵向增加 |
[[1 2 3 4] [5 6 7 8]] |
||
Series |
s= |
s.append() |
增加 Series |
|
s[4]=5 |
利用索引增加 |
|||
set |
st={1, 2, 3, 4} |
st.add(5) |
增加 |
{1,2,3,4,5} |
其他操作如删、改、查,大家可以自己查一下,很容易得出结论:同样的操作,不同的数据结构的语法完全不同。想要熟练掌握最好的办法就是死记硬背加刻意练习了。
集合运算
集合常做的运算就是交、差、并、和运算,而 Python 中的语法也是让人难以琢磨,给人一种每一类数据结构都是一门新语言的感觉,需要重新掌握语法,下面以集合的交集运算为例说明:
数据类型 |
例子 |
代码 |
结果 |
list |
l1=[1,2,3] l2=[2,3,4] |
insect_l=[val for val in l1 if val in l2] |
[2, 3] |
array |
a1=[1 2 3] a2=[2 3 4] |
insect_a=np.intersect1d(a1,a2) |
[2 3] |
Series |
s1= s2= |
insect_s=pd.merge(s1,s2,on="v") |
|
set |
st1={1,2,3} st2={2,3,4} |
insect_st=st1.intersection(st2) |
{2,3} |
list数据结构简单,没有现成的集合运算函数,只能自己编码来写;Seiries 除了用 merge 函数来做还可以转换为 array 后来做,但那就不能算是 Series 的操作了,四类数据结构,四种语法。
二维集合——表
集合介绍
Python中没有原生的二维表数据结构,比较常用的二维表结构是 Pandas 库中的 Dataframe,它也是 Series 的集合,形式如下:
Dataframe每一列都是一个 Series,每个 Series 不支持多类型元素,但 Dataframe 支持不同类型的 Series,如整列都是整数的 int 型 Series 和整列都是字符串的 object 型 Series,形式如下:
其中 number 列是 int64 类型,string 列是 object 类型。
Dataframe这个数据结构本身比较复杂,它不是我们经常见到的二维表结构,本质上是矩阵,所有的运算都要绕到矩阵上才可以运算。
基本操作
Dataframe 的操作和 Series 类似,两者算是一脉相承,还是以增加元素为例来介绍。
1. 增加行
df.loc[4]={"a":5}
结果:
2. 增加列
df["b"]=["a","b","c","d","e"]
结果:
对比一下 Series 的增加元素操作,道理是一样的,都可以通过索引来增加,只不过 Dataframe 多了一个维度。
集合运算
Dataframe的集合运算也和 Series 一样,来看看交集:
1. 创建两个 Dataframe:
df1=pd.DataFrame({"a":[2,3,4,5,6]})
df2=pd.DataFrame({"a":[3,4,5,6,7]})
结果:
2. 交集
insect_df=pd.merge(df1,df2,on="a")
结果:
Python可以很好的完成这些基本操作和集合运算,但只看这些简单例子就可以发现 Python 并不容易上手,尤其是 Numpy 和 Pandas 这两个第三方库,每一个都可以算是一门独立的语言了,想要达到熟练解决现实问题的程度,着实要下一番功夫不可。
esProc SPL
简单集合
集合介绍
SPL中的集合只有一种数据结构,就是序列,允许元素重复且顺序很重要。SPL 中的集合是泛化集合,允许不同类型的元素存在于集合中,甚至集合中的元素也可以是集合。
基本操作
SPL 中的集合操作简单,这里列举了序列的增删改查操作:
数据结构 |
例子 |
操作 |
代码 |
解释 |
结果 |
sequence |
s=[2,3,4,5] |
增 |
s1=s|6 |
末位增加 |
[2,3,4,5,6] |
s.insert(2,[1,7]) |
指定位置增加 |
[2,1,7,3,4,5] |
|||
删 |
s\[4,3] |
删除指定元素 |
[2,5] |
||
s.delete([2,4]) |
删除指定位置元素 |
[2,4] |
|||
改 |
s([1,3])=[8,9] |
修改指定位置的元素 |
[8,3,9,5] |
||
查 |
s([1,3,2]) |
按位置查 |
[2,4,3] |
语法简单,容易掌握。
集合运算
再来看下 SPL 的集合运算,利用符号操作更简单。
数据结构 |
例子 |
运算类型 |
代码 |
结果 |
sequence |
s1=[1,2,3,4] s2=[2,3,4,5] |
交集 |
s1^s2 |
[2,3,4] |
差集 |
s1\s2 |
[1] |
||
并集 |
s1&s2 |
[1,2,3,4,5] |
||
合集 |
s1|s2 |
[1,2,3,4,2,3,4,5] |
二维集合——表
集合介绍
SPL中的表称为序表,它本质上是带字段结构的序列。形式如下:
序表中的每一行称为一条记录,引用序表中的部分记录称为排列,记录可以游离于序表之外。
基本操作
序表的本质是序列,而记录就是它的元素,因此序表相对于记录就如同序列相对于元素,两者几乎完全一致。如序表和序列删除元素都是用 delete 函数,增加元素都是用 insert 函数。
1. 创建序表
T=[1,2,3,4].new(~:a)
结果:
2. 增加行
T=T.insert(0,5:a)
结果:
3. 删除行
T=T.delete([1,2])
结果:
集合运算
排列是引用序表中的部分记录,同样可以用符号来进行集合运算。
某个表筛选两个排列:
T=[2,3,4,5,6,7].new(~:a)
A1=T.select(a<7)
A2=T.select(a>2)
结果:
1. 交集
A1^A2
结果:
2. 差集
A1\A2
结果:
3. 并集
A1&A2
结果:
4. 合集
A1|A2
结果:
序表是独立的对象,两者没有可比性,因此集合运算时略显麻烦。
1. 创建序表
T1=[2,3,4,5,6].new(~:a)
T2=[3,4,5,6,7].new(~:a)
结果:
2. 交集
insect= [T1,T2].merge@i(a)
结果:
3. 差集
diff= [T1,T2].merge@d(a)
结果:
4. 并集
union= [T1,T2].merge@u(a)
结果:
5. 合集
conj=T1|T2
结果:
小结
Python的集合数据结构多种多样,同样的操作因为数据结构不同而完全不是一回事儿,有的数据结构简单好理解,但运算麻烦,比如列表 list;有的运算简单,但数据结构复杂,不好理解,比如 Series。这就需要用户掌握全部数据结构下的所有操作。而且 Python 没有原生的二维表这一数据结构,很多结构化数据处理起来非常不便,而第三方库 Pandas 虽然有 Dataframe 这一数据结构,但晦涩难懂,简单运算如交、差、并、合的集合运算都很复杂,实现起来复杂而且效率很低。
再来看 SPL,SPL 的数据结构简单,集合即序列,二维表也延续简单集合——序列这一结构,几乎所有的运算都是一脉相承,一旦掌握了简单的集合运算就可以写出简单高效的代码,真正的实现写得快还跑得快。
Python就像是野蛮生长的植物,适应能力虽然很强,但很难驾驭,原生 Python 又过于简单,使用起来繁琐且效率低,与其说 Python 是一门语言,不如说是 N 多第三方库语言的集合体;而 SPL 经过精心设计,擅长处理结构化数据,是一个十分容易掌握的专业工具。
英文版