在网络上的Pandas教程中,很多都提到了如何使用Pandas将已有的数据(如csv,如hdfs等)直接加载成Pandas数据对象,然后在其基础上进行数据分析操作,但是,很多时候,我们需要自己创建Pandas数据对象,并填入一些数据,常见的应用场景如:我们想要将现有的数据进行处理,并生成一个新的Pandas数据对象,还有,我们想利用Pandas的数据保存功能(比如to_csv, to_json, to_hdf等等)把我们采集到的数据写入到IO里边,因此掌握Pandas对象的特性,以及如何创建也是很重要的。
有些时候我们需要利用pandas数据结构创建自己的对象,按自己的方式保存新数据,我们将在本文中介绍如何实现。
1. Pandas的两种数据类型
Pandas支持两种数据类型,分别为Series和DataFrame,其中:
Series - 是一个带有标签的一维数组,支持多种不同的类型,但是针对同一个Series里边存储的数据类型必须是一致的
DataFrame - 是一个带有标签的二维数组,是一个尺寸可以修改的表格,一个DataFrame由多个Series组成,每一列都是一个Series
一句话描述的话就是,Series是很多标量数据(Scalar)的集合,而DataFrame是很多Series的集合。
我们来看下图这个例子,在1D的Series中,下图中有三个Series,分别保存了姓名(name), 年龄(age)和得分(marks),而他们的每一行都分别对应一个不同的人的信息,在每一个Series中的每一个单元格中(比如name series的第1行,对应的Prasadi)都是一个标量(Scalar),而每一行前边的0,1,2,3这些就是数据的索引(index),也可以叫做标签,所以说,Series是带有标签的一维数组。
可以看出,利用Series只能存储一种类型的数据,比如说name series存储的数据是字符串类型,而age series存储的数据是整数型。如果我们想把name,age,marks存储在一个数据结构里,我们就需要使用DataFrame,从图中看出,DataFrame类似于一个表格数据,有行有列,行跟Series的行一致,是数据的标签,而每一列就是原来的每一个Series。
2. Series类型
如我们在前文中所说,Series结构中可以存储任何类型的数据,包括:整型,字符串类型,浮点型,甚至是Python对象等等,但是要求是,每一行的数据类型必须统一。那么如何创建一个Series对象呢,
通过numpy array
Pandas的一个主要用途是数据分析,而它也是基于Numpy实现的,因此,通过numpy array来创建Series是非常常见的。
np_array = np.random.randn(5) pd.Series(np_array, index=['a', 'b', 'c', 'd', 'e'])
上边这段代码,利用np.random.randn随机生成一个长度为5的numpy array,然后pd.Series使用这个numpy array来创建一个Series,在创建的同时,指定了每一行的index(标签)分别是a,b,c,d,e,f,输出结果为:
通过Python字典
通过上边这个示例,大家有没有发现Series跟Python内置的dict类型是不是很类似,标签相当于dict中的key,而数据内容相当于dict中的value,它们有一一对应的关系,因此,可以想象,我们能够直接通过Python的dict来创建一个Series。
d = {'b': 1, 'a': 0, 'c': 2} pd.Series(d)
上边这段代码,我们先创建了一个Python地点d,然后将这个字典传递给pd.Series来创建一个Pandas Series,运行结果为:
通过标量值(Scalar)
除了上边这两种方式,我们还可以通过一个简单的标量值来创建Series,特别注意的是跟上边两种方式不同,在使用这种方式创建Series的时候,我们必须指定index
pd.Series(5, index=['a', 'b', 'c', 'd', 'e'])
如上边代码所示,我们使用一个常量5,然后指定index为a,b,c,d,e,同样使用pd.Series可以创建一个Series对象,看到这里我们就能够明白为什么必须指定Index了吧,那是因为Series对象是有长度的,长度是可以大于1的,而标量的长度固定为1,我们可以通过指定Index的方式来控制生成的Series的长度,Series中的值则是重复使用这一个标量常量5。其运行结果为:
name属性
当我们创建一个Series的时候,我们可以指定一个名称,这个名称会被存储到Series的name属性中,后续我们还可以使用rename方法来修改这个属性,例如下边这样的代码:
s = pd.Series(np.random.randn(5), name='this_is_name') s
创建了一个名称为this_is_name的Series,然后我们使用rename方法来重命名这个Series为this_is_new_name:
s = s.rename('this_is_new_name') s
上边这两部分代码的输入如下图:
那么这个名称有什么作用呢,这里预告一下,我们将在DataFrame中用到(别忘了DataFrame是多个Series的集合)
3. DataFrame类型
在第一节中我们介绍到,DataFrame是一个二维的表格数据结构,它有行和列的概念,跟行标签相对应的,为了能够按列索引数据,每一列都可以有一个名称,即列名,我们刚在Series章节中看到,Series可以表示一列数据,我们在本节中介绍的DataFrame就是多个这样的Series的组合,每一列就对应一个Series,而每一行也对应一个Series。读到这里,你是不是能够猜的出我们刚说的Series的name属性的用途了,对了,使用Series创建DataFrame的列的时候,Series的名称就会成为列名,如果Series作为行,则Series的名称会成为行名。
接下来我们来讲解如何创建DataFrame
通过一维numpy array或者Python List 组成的字典
大家可以想想,如果一个字典的value是array或者list的时候,那么这个字典其实就是一种表格结构,图为DataFrame是一个表格结构的数据类型,我们是可以通过这样的字典来创建DataFrame,例如下边这段代码
d = {'one': [1., 2., 3., 4.], 'two': [4., 3., 2., 1.]} pd.DataFrame(d, index=['a', 'b', 'c', 'd'])
我们把d这个Python字典传递给pd.DataFrame来创建新的DataFrame,同时我们可以通过指定index来指定DataFrame的行名(标签),上边代码的输出为
通过包含列表的Python List
我们再来想想一下,除了字典之外可以表示表格数据,还有没有其他的方法,是的,还有Python List,例如下边这段代码
data = [(1, 2., 'Hello'), (2, 3., "World")] pd.DataFrame(data)
我们可以用data这样的Python List来表示表格数据,不同于前边提到的字典(dict),用List表示的表格数据其实是没有行名和列名的,因此Pandas默认会自动生成行名和列名,所以上边的代码输出为:
当然,自动生成的行名列名没有任何意义,为了更好的操作数据,我们还可以通过设置pd.DataFrame方法的index或者columns参数来指定自己的行名或者列名。
通过包含Python 字典的Python List
我们继续想想,还有什么能够表示表格数据?对了,包含Python字典的Python List也是可以表达表格数据的,例如下边的代码
data = [{'a': 1, 'b': 2}, {'a': 5, 'b': 10, 'c': 20}] pd.DataFrame(data)
data是一个Python List,而列表中的每一个元素都是一个字典,运行结果为:
类似的,我们也可以通过指定index或者columns参数来修改行名和列名
通过Series
我们一直在提DataFrame是很多Series的集合(注:Series在DataFrame中可以是一行,也可以是一列),因此,我们也可以通过Series来创建DataFrame,例如下边这段代码
s1 = pd.Series(np.random.randn(5), name='this_is_name') df = pd.DataFrame(s1) df
利用s1这个Series来创建只有一列的DataFrame,输出结果为:
还记得不,我们前边提到了Series的name属性,在使用Series创建DataFrame的时候,这个属性会用来作为列名(或者行名,我们在下边的列子可以看得出),例如下边的这段代码,如果有两个Series,我们还可以用下边这样的方式创建DataFrame
s1 = pd.Series(np.random.randn(5), name='this_is_name') s2 = s.rename('this_is_new_name') df = pd.DataFrame([s1, s2]) df
这里我们使用了两个名分别为this_is_name和this_is_new_name的Series来创建DataFrame,得到的结果为:
到这里,相信读者已经对Pandas提供的数据类型有了一个全面的认识了,并且有能力自己创建Pandas数据结构,并存储自己的数据了,一个常见的应用场景就是我们通过爬虫获取到数据以后,可以将这些非结构化的数据以Pandas的表格格式保存,值得注意的是数据存储在Pandas数据结构中的时候,数据其实是在内存中的,当程序被关闭以后,数据就丢失了,如果我们需要将数据持久化保存到硬盘或者数据库中的话,则可以通过简单的调用Pandas提供的to_csv, to_json, to_hdf等等接口将数据永久保存下来。
更多Python Pandas库的相关文章,请点击下面的相关文章