深入浅出Pandas:利用Python进行数据处理与分析
上QQ阅读APP看书,第一时间看更新

2.5 Pandas生成数据

今后我们处理的数据基本上是Pandas的DataFrame和Series,其中DataFrame是Series的容器,所以需要掌握数据生成方法。现在我们学习如何制造一些简单数据放入DataFrame和Series,后面会单独讲解如何从文件(如Excel)中读取和生成数据。

2.5.1 导入Pandas

我们在使用Pandas时,需要先将其导入,这里我们给它取了一个别名pd。起别名是因为Pandas这个单词有点长,在代码中会经常出现,这样会简单些,减少代码量。别名可以自由选择,但pd是pandas的简写,已经约定俗成,方便自己和别人看懂你的代码,所以建议不要起别的名字。

如果出现类似ModuleNotFoundError: No module named 'pandas'的错误,说明没有安装Pandas模块,可参见第1章进行环境搭建并使用pip install pandas安装。

如果执行导入库后,没有返回任何内容,说明库导入成功,可以使用pd来调用Pandas的功能了。如果需要NumPy的功能,则需要将其引入并起别名np,同样np已经约定俗成。最终的代码为:

import pandas as pd
import numpy as np

2.5.2 创建数据

使用pd.DataFrame()可以创建一个DataFrame,然后用df作为变量赋值给它。df是指DataFrame,也已约定俗成,建议尽量使用。

df = pd.DataFrame({'国家': ['中国', '美国', '日本'],
                   '地区': ['亚洲', '北美', '亚洲'],
                   '人口': [13.97, 3.28, 1.26],
                   'GDP': [14.34, 21.43, 5.08],
                  })

pd.DataFrame()为一个字典,每条数据为一个Series,键为表头(列索引),值为具体数据。执行变量df的结果如下:

   国家  地区   人口    GDP
0  中国  亚洲  13.97  14.34
1  美国  北美   3.28  21.43
2  日本  亚洲   1.26   5.08

可以看到,我们成功生成了一个DataFrame:

  • 共有4列数据,国家、地区、人口和GDP;
  • 4列数据中国家和地区是文本类型,人口和GDP是数字;
  • 共3行数据,系统为我们自动加了索引0、1、2。

我们知道,DataFrame可以容纳Series,所以在定义DataFrame时可以使用Series,也可以利用NumPy的方法:

df2 = pd.DataFrame({'A': 1.,
                    'B': pd.Timestamp('20130102'),
                    'C': pd.Series(1, index=list(range(4)), dtype='float32'),
                    'D': np.array([3] * 4, dtype='int32'),
                    'E': pd.Categorical(["test", "train", "test", "train"]),
                    'F': 'foo'})
df2
'''
     A          B    C  D      E    F
0  1.0 2013-01-02  1.0  3   test  foo
1  1.0 2013-01-02  1.0  3  train  foo
2  1.0 2013-01-02  1.0  3   test  foo
3  1.0 2013-01-02  1.0  3  train  foo
'''

上面D列使用np.array()方法构建了一个数量为4的整型数列。

从DataFrame中选取一列就会返回一个Series,当然选择多列的话依然是DataFrame。

df['人口']
'''
0    13.973
1     3.28
2     1.26
Name: 人口, dtype: float64
'''

如下单独创建一个Series:

s = pd.Series([14.34, 21.43, 5.08], name='gdp')
s
'''
0    14.34
1    21.43
2     5.08
Name: gdp, dtype: float64
'''

使用Python的type函数可以查看数据类型:

type(s) # pandas.core.series.Series
type(df) # pandas.core.frame.DataFrame

2.5.3 生成Series

Series是一个带有标签的一维数组,这个数组可以由任何类型数据构成,包括整型、浮点、字符、Python对象等。它的轴标签被称为索引,它是Pandas最基础的数据结构。

Series的创建方式如下:

s = pd.Series(data, index=index)

data可以是Python对象、NumPy的ndarray、一个标量(定值,如8)。index是轴上的一个列表,必须与data的长度相同,如果没有指定,则自动从0开始,表示为[0, …, len(data)–1]。

(1)使用列表和元组

列表和元组可以直接放入pd.Series():

pd.Series(['a', 'b', 'c', 'd', 'e'])
pd.Series(('a', 'b', 'c', 'd', 'e'))

(2)使用ndarray

如下使用NumPy的ndarray结构:

# 由索引分别为a、b、c、d、e的5个随机浮点数数组组成
s = pd.Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])
s.index # 查看索引
s = pd.Series(np.random.randn(5)) # 未指定索引

(3)使用字典

如下使用Python的字典数据:

d = {'b': 1, 'a': 0, 'c': 2}
s = pd.Series(d)
s
'''
b    1
a    0
c    2
dtype: int64
'''

# 如果指定索引,则会按索引顺序,如有无法与索引对应的值,会产生缺失值
pd.Series(d, index=['b', 'c', 'd', 'a'])
'''
b    1.0
c    2.0
d    NaN
a    0.0
dtype: float64
'''

(4)使用标量

对于一个具体的值,如果不指定索引,则其长度为1;如果指定索引,则其长度为索引的数量,每个索引的值都是它。

pd.Series(5.)
'''
0    5.0
dtype: float64
'''

# 指定索引
pd.Series(5., index=['a', 'b', 'c', 'd', 'e'])
'''
a    5.0
b    5.0
c    5.0
d    5.0
e    5.0
dtype: float64
'''

2.5.4 生成DataFrame

DataFrame是二维数据结构,数据以行和列的形式排列,表达一定的数据意义。DataFrame的形式类似于CSV、Excel和SQL的结果表,有多个数据列,由多个Series组成。

DataFrame最基本的定义格式如下:

df = pd.DataFrame(data=None, index=None, columns=None)

以下是其各参数的说明。

  • data:具体数据,结构化或同构的ndarray、可迭代对象、字典或DataFrame。
  • index:索引,类似数组的对象,支持解包,如果没有指定,会自动生成RangeIndex (0, 1, 2, …, n)。
  • columns:列索引、表头,如果没有指定,会自动生成RangeIndex (0, 1, 2, …, n)。

此外还可以用dtype指定数据类型,如果未指定,系统会自动推断。

大多数情况下,我们是从数据文件(如CSV、Excel)中取得数据,不过,了解这部分知识可以让我们更好地理解DataFrame的数据机制。

1. 字典

字典中的键为列名,值一般为一个列表或者元组,是具体数据。示例如下。

d = {'国家': ['中国', '美国', '日本'],
     '人口': [14.33, 3.29, 1.26]}
df = pd.DataFrame(d)
df
'''
   国家    人口
0  中国  13.97
1  美国   3.28
2  日本   1.26
'''

如果生成时指定了索引名称,会使用指定的索引名,如a、b、c。示例如下。

df = pd.DataFrame(d, index=['a', 'b', 'c'])
df
'''
   国家    人口
a  中国  13.97
b  美国   3.28
c  日本   1.26
'''

2. Series组成的字典

这是一种非常典型的构造数据的方法,字典里的一个键值对为一列数据,键为列名,值是一个Series。示例如下。

d = {'x': pd.Series([1., 2., 3.], index=['a', 'b', 'c']),
     'y': pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)
df
'''
     x    y
a  1.0  1.0
b  2.0  2.0
c  3.0  3.0
d  NaN  4.0
'''

3. 字典组成的列表

由字典组成一个列表,每个字典是一行数据,指定索引后会使用指定的索引。示例如下。

# 定义一个字典列表
data = [{'x': 1, 'y': 2}, {'x': 3, 'y': 4, 'z': 5}]

# 生成DataFrame对象
pd.DataFrame(data)
'''
   x  y    z
0  1  2  NaN
1  3  4  5.0
'''

# 指定索引
pd.DataFrame(data, index=['a', 'b'])
'''
   x  y    z
a  1  2  NaN
b  3  4  5.0
'''

4. Series生成

一个Series会生成只有一列的DataFrame,示例如下。

s = pd.Series(['a', 'b', 'c', 'd', 'e'])
pd.DataFrame(s)

5. 其他方法

以下两个方法可以从字典和列表格式中取得数据。

# 从字典里生成
pd.DataFrame.from_dict({'国家': ['中国', '美国', '日本'],'人口': [13.97, 3.28, 1.26]})
# 从列表、元组、ndarray中生成
pd.DataFrame.from_records([('中国', '美国', '日本'), (13.97, 3.28, 1.26)])
# 列内容为一个字典
pd.json_normalize(df.col)
df.col.apply(pd.Series)

2.5.5 小结

本节介绍了Pandas的DataFrame和Series结构数据的生成,是后面编写数据分析代码的基础。在实际业务中一般不需要我们来生成数据,而是有已经采集好的数据集,直接加载到DataFrame即可。