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 经过精心设计,擅长处理结构化数据,是一个十分容易掌握的专业工具。