第94天:数据分析之 pandas 初步

简介: 第94天:数据分析之 pandas 初步

pandas是一个常用的第三方 Python 库,提供快速灵活的数据处理功能,也是进行数据分析的有力工具。我们的口号是:“更快,更高,更强”(皮一下)。啊,当然,现在经常有很多库一上来就要“吊打”pandas,咱们还是不必在意。


pandas尤其擅长处理以下数据:


以下几种数据尤其适合用pandas进行处理:


  • 多种数据混合的扁平化数据格式,比如 SQL 表和 Excel 电子表格;
  • 时间序列数据,不管有序无序;
  • 任意带有行列标签的矩阵数据,不管是同种数据类型还是多种数据类型;
  • 还有其他任意的统计数据集,不必带标签。


在本文开头要提醒的是,pandas指的不是英语中的“panda”,熊猫。实际上pandas是术语“panel data”(面板数据)的简写,大家要注意:这不是国宝模块哈哈,不要看到这个模块就想起憨憨的大熊猫啦~


1. pandas 安装


有了之前文章的铺垫,其实安装这个步骤大家应该已经很熟悉了,但是在这里依然要再叙述一遍。已经安装好的同学跳过就好。


由于pandas并非 Python 的内置模块,因此我们直接从 Python 官网下载安装的发行版是不包含 pandas这个模块的。这个时候你要是想import numpy,显然是会无功而返的。因此我们需要额外安装 pandas模块。


安装 pandas有好几种方式,我们这里推荐的是:1)使用pip进行安装;2)安装 Anaconda。


1.1 使用pip安装


这种方式推荐给已经从 Python 官网下载了某个 Python 发行版的读者,或是已经通过其它方式获得了 Python 环境,但却没有 pandas这个模块的读者。

安装命令:


pip install pandas

或:


python -m pip install pandas

均可。


当然,实际上 pandas模块本身也有很多依赖,也需要其他一些模块才能够真正发挥出它强大的功能,因此我们推荐一次安装多个模块:


python -m pip install --user numpy scipy matplotlib ipython jupyter pandas sympy nose


1.2 安装 Anaconda


这种方式适合还没有安装 Python 的读者,或是已经安装了 Python 但是想一劳永逸拥有大多数科学计算库的读者。


访问 https://www.anaconda.com/ 官网找到下载链接进行安装即可。


或者如果你觉得 Anaconda 过于臃肿,也可以安装其简化版本 https://docs.conda.io/en/latest/miniconda.html


2. 主要数据类型


pandas中有两个主要的数据类型,一种是 Series,称为“序列”,是一种一维数据结构;另一种是 DataFrame,称为“数据帧”或是“数据框架”,是一种二维数据结构。在pandas中,我们就是使用这两种主要的数据结构,“喜迎四海宾朋,笑对八方来客”,分分钟处理掉天上地下来的各种数据。


其中,Series 内部要求是同种数据,而 DataFrame 则可以使混合数据。更进一步地说, DataFrame 其实就是包含了一至多个 Series


前面我们学习了numpy模块的基本相关知识,如果大家还有印象的话可以回忆一下。


numpy虽然提供了强大的多维数组供我们进行数据处理,但是这中间有一个要命的问题:维数比较少的时候还好,维数一旦多起来,你还分得清哪个轴代表什么意义吗?呃当然不排除有人可以,但是大多数人肯定是不行的,因为numpy的每个轴之间其实没有什么本质上的差异,你可以是轴 1,我也可以是轴 1,谁有比谁高贵怎么滴?因此在使用numpy进行高维数据处理,尤其是当其中每个维度都有特定的意义时,使用numpy的多维数组就会给使用者造成很大的负担——而这些本来不应该是由使用者负担的。


因此pandas的优势就体现出来了。pandas可以为每一列数据打上标签,这样通过标签就可以直接区分开每个轴谁是谁,也可以通过标签获得更具语义性的信息,知道每列数据都是什么、有什么用途。即使是交换了顺序也无所谓,比较在pandas中,我们可以不再以默认的序号作为索引。


当然pandas还有可以组合多种数据类型等优势,这些就留待大家在实践中体会啦~

我们预先导入pandas,并且由于演示过程中会用到numpy模块,在这里也一并导入:


import numpy as npimport pandas as pd


2.1 Series


Series 实际上是一个带标签的一维数组,数组中的内容可以是任何数据类型。在 Series 中,“带标签的轴”统称为“index(索引)”,类似于我们之前学习的字典数据类型中的“key(关键字)”。


2.1.1 创建 Series


创建 Series 最常用的方法就是调用pd.Series


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


其中,data要求是下列数据类型之一:

  • Python 字典;
  • Python 列表;
  • N 维数组;
  • 标量(即一个数字)。


而参数index则应当是一个用来指定轴标签的列表。


按照原始数据类型的不同,创建 Series 的方式也分为 4 种:1)用 Python 字典创建;2)用 Python 列表创建;3)用 N 维数组创建;4)用标量创建。

  1. Python 字典


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


>>> l = [1,2,3]>>> s = pd.Series(l)>>> s0    11    22    3dtype: int64

可以看到,在只使用列表而不提供索引值时,pandas会自动为 Series 中的数据分配默认索引作为标签。

  1. N 维数组



>>> ar = np.random.randn(5)>>> ararray([-0.12383463,  0.2312694 ,  1.82605315, -1.4743252 , -0.71267657])>>> s = pd.Series(ar, index=['a', 'b', 'c', 'd', 'e'])>>> sa   -0.123835b    0.231269c    1.826053d   -1.474325e   -0.712677dtype: float64
  1. 标量


>>> # 标量生成单元素序列>>> s = pd.Series(5.)>>> s0    5.0dtype: float64>>> >>> # 标量生成多元素序列>>> s = pd.Series(5., index=['a', 'b', 'c', 'd', 'e'])>>> sa    5.0b    5.0c    5.0d    5.0e    5.0dtype: float64


2.1.2 索引 Series


既然说到 Series 类似于一维数组,也就是说 Series 也可以通过序号进行索引:


>>> s = pd.Series([5,-4,7,-8,9], index=['a','b','c','d','e'])>>> sa    5b   -4c    7d   -8e    9dtype: int64>>> s[2]7>>> s[1]-4


其次,Series 还可以通过标签进行索引:

>>> s['a']5>>> s['d']-8


并且 Series 也有切片功能:



>>> s[1:3]b   -4c    7dtype: int64>>> s[:3]a    5b   -4c    7dtype: int64

甚至标签也可以用于切片:


>>> s['a':'d']a    5b   -4c    7d   -8dtype: int64


都是观察可以发现,使用标签进行索引与使用序号进行索引还是存在一点儿不同:使用序号进行索引时,切片结果不会包括结束序号对应的内容;但使用标签进行索引就会包括末尾标签指定的内容。


还可以从 Series 中直接选取特定的项。同样地,也是既可以使用序号,也可以使用标签,但要记得将指定的序号或标签放在一个列表中:


>>> # 使用序号>>> s[[1,2]]b   -4c    7dtype: int64>>> >>> # 使用标签>>> s[['a','d']]a    5d   -8dtype: int64

此外还有根据条件进行筛选的用法,这种用法是一种pandasif-then方言:


>>> s[s > 0]a    5c    7e    9dtype: int64

这样就提取出了s中大于 0 的部分。

还要注意,Series 的直接赋值不会创建副本,如果想要新的 Series 对象与旧的没有关系,需要显式地创建副本并赋值:


>>> s2 = s>>> s2 is sTrue>>> s2 = s.copy()>>> s2 is sFalse


2.1.3 Series 的运算


类似numpy数组地,Series 的算术运算——包括应用于很多numpy中的函数——也是逐元素进行的:


>>> s + sa    10.0b    -8.0c    14.0d   -16.0e    18.0dtype: float64>>> s * 2a    10.0b    -8.0c    14.0d   -16.0e    18.0dtype: float64>>> np.exp(s)a     148.413159b       0.018316c    1096.633158d       0.000335e    8103.083928dtype: float64

而 Series 与numpy数组的不同之处在于,Series 有自动对齐的特性,也就是说,在运算中如果两个参与运算的 Series 数据长度不一样,pandas会自动用默认的缺省值补全缺失的部分,以使运算顺利进行:


>>> s[1:] + s[:-1]a     NaNb    -8.0c    14.0d   -16.0e     NaNdtype: float64

简单来讲,在运算时如果遇到了“在某个运算对象中找不到对应项标签”的情况,那么pandas就会自作主张用缺省值NaN来代替。这就使得在进行交互式数据分析的时候有了极大的灵活性。


2.2 DataFrame


2.2.1 创建 DataFrame


DataFrame 是一种二维带标签的数据结构,并且允许各列直接数据类型不同。我们既可以把它当做是电子表格或是 SQL 表,也可以将其当作是一个由若干个 Series 对象组成的字典;也是pandas中最常用的数据结构。


创建 DataFrame 的方法是调用pd.DataFrame


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

其中的data参数要求是下列数据类型之一:


  • 由一维数组、列表、字典或是 Series 构成的字典;
  • 二维 Numpy 数组;
  • 结构化数组;
  • 一个 Series;
  • 别的 DataFrame。


参数index对应于 DataFrame 中的行标签,参数columns对应于DataFrame 中的列标签。通过指定这两个参数,可以有筛选使用哪些数据来生成 DataFrame。


在这里我们仅仅介绍 3 中可能用到的方法。


  1. 使用由 Series 组成的字典由字典组成的的字典来创建 DataFrame


如果不指定columns参数的话,默认将columns设置为字典关键字的有序列表。


>>> d = {'one': pd.Series([1., 2., 3.], index=['a', 'b', 'c']),...      'two': pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}>>> df = pd.DataFrame(d, index=['d', 'b', 'a'])>>> df   one  twod  NaN  4.0b  2.0  2.0a  1.0  1.0>>> df = pd.DataFrame(d, index=['d', 'b', 'a'], columns=['two', 'three'])>>> df   two threed  4.0   NaNb  2.0   NaNa  1.0   NaN>>> >>> # 默认形式>>> df = pd.DataFrame(d)>>> df   one  twoa  1.0  1.0b  2.0  2.0c  3.0  3.0d  NaN  4.0
  1. 使用 N 维数组或列表的字典


>>> d = {'one': [1., 2., 3., 4.],...      'two': [4., 3., 2., 1.]}>>> pd.DataFrame(d)   one  two0  1.0  4.01  2.0  3.02  3.0  2.03  4.0  1.0>>> pd.DataFrame(d, index=['a', 'b', 'c', 'd'])   one  twoa  1.0  4.0b  2.0  3.0c  3.0  2.0d  4.0  1.0
  1. 使用字典组成的列表



>>> data2 = [{'a': 1, 'b': 2}, {'a': 5, 'b': 10, 'c': 20}]>>> pd.DataFrame(data2)   a   b     c0  1   2   NaN1  5  10  20.0>>> pd.DataFrame(data2, index=['first', 'second'])        a   b     cfirst   1   2   NaNsecond  5  10  20.0>>> pd.DataFrame(data2, columns=['a', 'b'])   a   b0  1   21  5  10


2.2.2 索引 DataFrame


通过indexcolumns两个属性可以分别查看 DataFrame 的行标签和列标签:


>>> d = {'one': pd.Series([1., 2., 3.], index=['a', 'b', 'c']),...       'two': pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}>>> df = pd.DataFrame(d)>>> df   one  twoa  1.0  1.0b  2.0  2.0c  3.0  3.0d  NaN  4.0>>> df.indexIndex(['a', 'b', 'c', 'd'], dtype='object')>>> df.columnsIndex(['one', 'two'], dtype='object')

可以使用列标签来索引:


>>> df['one']a    1.0b    2.0c    3.0d    NaNName: one, dtype: float64

也可以直接将列标签作为属性:


>>> df.onea    1.0b    2.0c    3.0d    NaNName: one, dtype: float64

还可以按列选取:


>>> df[['one', 'two']]   one  twoa  1.0  1.0b  2.0  2.0c  3.0  3.0d  NaN  4.0

要对 DataFrame 按行索引,则需要使用loc这个属性:


>>> df.loc['a']one    1.0two    1.0Name: a, dtype: float64

同样地,也可以通过行标签来按行切片、选取:


>>> df.loc['a':'c']   one  twoa  1.0  1.0b  2.0  2.0c  3.0  3.0>>> df.loc[['a','d']]   one  twoa  1.0  1.0d  NaN  4.0

此外,还可以使用headtail来分别获取数据的前、后几行,具体数目由参数指定:


>>> df.head(2)   one  twoa  1.0  1.0b  2.0  2.0>>> df.tail(2)   one  twoc  3.0  3.0d  NaN  4.0


2.2.3 统计信息


使用describe可以计算得到一个 DataFrame 数据的相关统计信息,并且计算统计信息时会自动忽略缺省值NaN


>>> df   one  twoa  1.0  1.0b  2.0  2.0c  3.0  3.0d  NaN  4.0>>> df.describe()       one       twocount  3.0  4.000000mean   2.0  2.500000std    1.0  1.290994min    1.0  1.00000025%    1.5  1.75000050%    2.0  2.50000075%    2.5  3.250000max    3.0  4.000000

其中count是各列的数据个数,mean是各列数据的平均值,std则对应标准差,后续的各行为从最小值到最大值的均匀数据。

还可以使用median方法主动求出平均值:


>>> df.median() # 也适用于 Seriesone    2.0two    2.5dtype: float64


2.3 其他

Series 和 DataFrame 都可以使用同样的方法转换为numpy数组的形式:


>>> s.to_numpy()array([ 5., -4.,  7., -8.,  9.])

此外,两种主要数据结构还有一个叫做apply的方法,用来对实例调用指定的函数。可以指定已有的函数,也可以临时定义一个匿名函数,后者更加常见一些:


>>> df.apply(len)one    4two    4dtype: int64>>> df.apply(lambda x: x * x)   one   twoa  1.0   1.0b  4.0   4.0c  9.0   9.0d  NaN  16.0


3. 读取数据


实际上,大多数时候我们并不会手动创建一个 Series 或是 DataFrame,更一般的方法是通过使用pandas的读写接口,直接从文件中读取需要处理的数据。


为了演示pandas读取数据的功能,我们提供了一个真实的数据集,其中包含加利福尼亚州住房数据。同学们可以从“代码示例”获取该文件;也可直接使用示例代码中指定的 URL 进行下载。


california_housing_dataframe = pd.read_csv("/data/california_housing_train.csv", sep=",")

使用columns来看看有哪些种类的数据:


>>> california_housing_dataframe.columnsIndex(['longitude', 'latitude', 'housing_median_age', 'total_rooms',       'total_bedrooms', 'population', 'households', 'median_income',       'median_house_value'],      dtype='object')


pandas提供了大量函数用于文件读写,适用于 CSV、Excel、HDF、SQL、JSON、HTML 等文件类型,还包括一个读取系统剪贴板的接口pd.read_clipboard()


4. pandas 画图


上一节我们读取了一个真实的数据集,现在让我们针对其中意义最丰富的属性median_house_value(即平均房价)这一列,来画个直方图瞧一瞧:


>>> import matplotlib.pyplot as plt>>> california_housing_dataframe.hist('median_house_value')array([[<matplotlib.axes._subplots.AxesSubplot object at 0x00000222934BC8D0>]],      dtype=object)>>> plt.show()

image.png


后我们使用latitude作为 x 轴,以latitude作为 y 轴,考察一下加州房价在南北走向上的分布:


>>> california_housing_dataframe.plot.scatter(y='median_house_value',x='latitude')<matplotlib.axes._subplots.AxesSubplot object at 0x000002229301C7B8>>>> plt.show()

image.png


图上我们可以看到,加州的房价在南北走向上有两个高价带。

再考察一下东西走向上的分布:


>>> california_housing_dataframe.plot.scatter(y='median_house_value',x='longitude')<matplotlib.axes._subplots.AxesSubplot object at 0x00000222939A87B8>>>> plt.show()

image.png


以看到,加州房价在东西走向上也出现了两个高价带。显然加州高价房应该是集中在两个区域,我们可以通过对应的经纬度,找到这两个区域。


最后我们将经纬度分别作为 x、y 轴,将平均房价作为 z 轴画出一个三维图像,直观地观察一下:


>>> from mpl_toolkits.mplot3d import Axes3D>>> x = california_housing_dataframe['longitude']>>> y = california_housing_dataframe['latitude']>>> z = california_housing_dataframe['median_house_value']>>> fig = plt.figure()>>> ax = Axes3D(fig)>>> ax.scatter(x,y,z)<mpl_toolkits.mplot3d.art3d.Path3DCollection object at 0x00000222943317B8>>>> plt.show()

image.png


过拖动 3D 图像转换视角,容易看出确实有两个区域集中分布着高价房。


5. 总结


本文初步介绍了pandas模块中最核心的两个数据类型:Series 和 DataFrame,以及它们的一些性质。


通过演示读取数据和使用pandas画图,我们熟悉了pandas的基本操作,也感受了一下数据可视化的效果。


示例代码:https://github.com/JustDoPython/python-100-day

参考资料

https://pandas.pydata.org/pandas-docs/stable/index.html

https://colab.research.google.com/notebooks/mlcc/intro_to_pandas.ipynb

https://blog.csdn.net/genome_denovo/article/details/78322628

目录
相关文章
|
1月前
|
数据采集 存储 数据挖掘
Python数据分析:Pandas库的高效数据处理技巧
【10月更文挑战第27天】在数据分析领域,Python的Pandas库因其强大的数据处理能力而备受青睐。本文介绍了Pandas在数据导入、清洗、转换、聚合、时间序列分析和数据合并等方面的高效技巧,帮助数据分析师快速处理复杂数据集,提高工作效率。
74 0
|
3月前
|
数据采集 数据挖掘 数据处理
使用Python和Pandas进行数据分析基础
使用Python和Pandas进行数据分析基础
65 5
|
1月前
|
机器学习/深度学习 数据采集 数据挖掘
解锁 Python 数据分析新境界:Pandas 与 NumPy 高级技巧深度剖析
Pandas 和 NumPy 是 Python 中不可或缺的数据处理和分析工具。本文通过实际案例深入剖析了 Pandas 的数据清洗、NumPy 的数组运算、结合两者进行数据分析和特征工程,以及 Pandas 的时间序列处理功能。这些高级技巧能够帮助我们更高效、准确地处理和分析数据,为决策提供支持。
42 2
|
1月前
|
存储 数据挖掘 数据处理
Python数据分析:Pandas库的高效数据处理技巧
【10月更文挑战第26天】Python 是数据分析领域的热门语言,Pandas 库以其高效的数据处理功能成为数据科学家的利器。本文介绍 Pandas 在数据读取、筛选、分组、转换和合并等方面的高效技巧,并通过示例代码展示其实际应用。
45 2
|
1月前
|
数据采集 数据可视化 数据挖掘
Python数据分析:Pandas库实战指南
Python数据分析:Pandas库实战指南
|
1月前
|
并行计算 数据挖掘 大数据
Python数据分析实战:利用Pandas处理大数据集
Python数据分析实战:利用Pandas处理大数据集
|
1月前
|
数据采集 数据可视化 数据挖掘
利用Python进行数据分析:Pandas库实战指南
利用Python进行数据分析:Pandas库实战指南
|
2月前
|
机器学习/深度学习 数据采集 算法
探索Python科学计算的边界:NumPy、Pandas与SciPy在大规模数据分析中的高级应用
【10月更文挑战第5天】随着数据科学和机器学习领域的快速发展,处理大规模数据集的能力变得至关重要。Python凭借其强大的生态系统,尤其是NumPy、Pandas和SciPy等库的支持,在这个领域占据了重要地位。本文将深入探讨这些库如何帮助科学家和工程师高效地进行数据分析,并通过实际案例来展示它们的一些高级应用。
61 0
探索Python科学计算的边界:NumPy、Pandas与SciPy在大规模数据分析中的高级应用
|
2月前
|
数据采集 数据挖掘 API
Python数据分析加速器:深度挖掘Pandas与NumPy的高级功能
在Python数据分析的世界里,Pandas和NumPy无疑是两颗璀璨的明星,它们为数据科学家和工程师提供了强大而灵活的工具集,用于处理、分析和探索数据。今天,我们将一起深入探索这两个库的高级功能,看看它们如何成为数据分析的加速器。
47 1
|
3月前
|
数据挖掘 Python
Pandas实战(1):电商购物用户行为数据分析
Pandas实战(1):电商购物用户行为数据分析
119 1
下一篇
DataWorks