0.数据分析环境准备
工欲善其事,必先利其器,在进行数据分析之前,介绍常用的python数据分析环境。可以根据实际情况选择合适的数据分析环境。
Ipython
IPython是一个交互式的Python解释器,它提供了丰富的数据分析功能,包括数据可视化、数据导入导出、数据计算、代码调试等。
Jupyter Notebook
Jupyter Notebook是基于IPython的Web开发工具,它可以帮助我们创建和编辑各种类型的文档,包括代码、文本、图像、表格等。Jupyter Notebook支持在单个文档中同时运行多个代码块,可以让我们更加方便地进行数据分析和可视化。
JupyterLab
JupyterLab是基于Jupyter Notebook的Web开发环境,它可以帮助我们创建和编辑各种类型的文档,包括代码、文本、图像、表格等。JupyterLab还支持在多个标签页中同时运行多个代码块,可以让我们更加方便地进行数据分析和可视化。
Anaconda
Anaconda是一个Python数据科学发行版,它包含了一系列与数据分析相关的Python库,如NumPy、Pandas、Matplotlib等。Anaconda还提供了一个交互式的Python解释器,可以让我们更加方便地进行数据分析和可视化。
conda-forge
conda-forge是一个专门为Python数据科学家提供各种Python库的发行版,其中包含了许多与数据分析相关的库,如Seaborn、Waffle等。conda-forge还支持在线安装和更新Python库,可以让我们更加方便地进行数据分析和可视化。
Pycharm
PyCharm是一款由捷克公司JetBrains开发的Python集成开发环境,它可以用来开发Python web应用程序、科学计算、数据分析等应用领域。PyCharm具有代码提示、自动补全、调试等功能,可以帮助开发者更高效地开发Python程序。Pycharm作为一款强大的python开发工具,用其来做数据分析自然不在话下,另外还提供了丰富的插件支持,可以进一步提高效率。
1.Pandas介绍
1.1 Pandas简介
Pandas是一个强大的Python库,主要用于数据分析和处理。它提供了高效的数据结构和数据分析工具,让数据的操作变得更加简单和方便。Pandas的核心目标是为用户提供简单易用的数据结构和数据操作工具,从而使用户能够更快地完成数据分析和处理任务。
Pandas提供了一系列灵活、高效的数据结构和数据操作工具,包括DataFrame、Series、Index等。这些数据结构和工具可以帮助用户快速地读取、处理、合并、汇总、排序、分组、统计等各种数据操作任务。 Pandas之所以在数据分析和处理中如此受欢迎,主要是因为它提供了一系列高效、灵活的数据结构和数据操作工具,可以帮助用户快速地完成各种数据分析和处理任务。此外,Pandas还支持大量的数据源,包括CSV、Excel、SQL数据库等,从而使用户可以方便地从各种数据源中读取数据。另外,Pandas还支持Python的大量第三方库,从而使用户可以方便地与其他Python库进行集成,从而实现更加复杂的数据分析和处理任务。
1.2 主要数据结构
pandas主要有两种数据结构,即Series和DataFrame。
Series是一种类似于一维数组的数据结构,可以用来表示一组有序数据。DataFrame是一种二维表格数据结构,可以用来表示有关联关系的数据。
- Series可以看作是DataFrame的一列,DataFrame可以看作是Series的多列。
- Series和DataFrame都支持常见的数据操作,如索引、排序、求和、平均值等。
以下是创建Series和创建DataFrame的示例:
import pandas as pd
import numpy as np
# 创建Series
data = np.array([1, 2, 3, 4, 5])
s = pd.Series(data)
print('s:\n', s)
# 创建Dataframe
data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
df = pd.DataFrame(data, columns=['A', 'B', 'C'])
print('df:\n', df)
#输出结果:
s:
0 1
1 2
2 3
3 4
4 5
dtype: int32
df:
A B C
0 1 2 3
1 4 5 6
2 7 8 9
Series和DataFrame两种数据结构也是可以相互转化的,Series可以变成DataFrame中的一列,反之DataFrame取一列即为Series。
# Series转DataFrame
s2df = pd.DataFrame(s, columns=['A'])
# DataFrame转Series
df2s = df['A']
print(type(s2df), type(df2s))
#输出结果
<class 'pandas.core.frame.DataFrame'> <class 'pandas.core.series.Series'>
2.基础操作
将运行环境准备好,同时介绍了Pandas相关内容之后,接下来可以直接上代码了
2.1 创建数据集
2.1.1 直接创建
当数据量小时,可以直接创建Series或者DataFrame
# 除了上一节中通过list创建Ser的方式之外,还可以通过dict创建
# 创建Series时,dict中的key此时变为Series的索引
data = {'a': 1, 'b': 2, 'c': 3}
s = pd.Series(data)
#创建DataFrame时,注意数据结构的变化
data = {'a': [1, 2, 3], 'b': ['1', '2', '3'], 'c': ['a', 'b', 'c']}
df = pd.DataFrame(data)
#输出结果:
s:
a 1
b 2
c 3
dtype: int64
df
a b c
0 1 1 a
1 2 2 b
2 3 3 c
2.1.2 从外部数据源加载
除了直接创建,Pandas还支持丰富的外部数据源加载方式,查看Pandas读取外部数据源相关的函数,有以下几类:
'read_clipboard', 'read_csv', 'read_excel', 'read_feather', 'read_fwf', 'read_gbq', 'read_hdf', 'read_html', 'read_json', 'read_orc', 'read_parquet', 'read_pickle', 'read_sas', 'read_spss', 'read_sql', 'read_sql_query', 'read_sql_table', 'read_stata', 'read_table'
接下来介绍最常用的集中外部数据源加载方式的基本的用法:
- 从csv文件创建DataFrame
# data.csv为一个以逗号作为分隔符的数据文件
df = pd.read_csv('data.csv')
read_csv有很多可选的参数,如不指定均为默认值,其他定制化的参数如下:
filepath_or_buffer:CSV文件路径或文件对象,必选参数。
sep:字段分隔符,默认为逗号(,)。 header:指定哪一行作为列名,默认为0,即第一行。
names:指定列名列表,如果header=None,则必须指定。
index_col:指定哪一列作为行索引,默认为None,即不指定。
usecols:指定要读取的列名或列索引列表,默认为None,即读取所有列。
dtype:指定每一列的数据类型,可以是字典或函数。
skiprows:指定要跳过的行数,可以是整数或列表。
nrows:指定要读取的行数,可以是整数。
skip_blank_lines:是否跳过空行,默认为True。
na_values:指定缺失值的表示方式,可以是字符串、列表或字典。
encoding:指定文件编码方式,默认为None,即自动检测。
delimiter:字段分隔符,与sep参数相同。
comment:注释符号,默认为None,即不使用注释。
quoting:引号的处理方式,默认为0,即不处理引号。
skipinitialspace:是否跳过字段前的空格,默认为False。
error_bad_lines:是否跳过格式不正确的行,默认为True。
warn_bad_lines:是否在跳过格式不正确的行时发出警告,默认为True。
- 从json文件创建DataFrame
# data.json为一个包含json格式的数据的文件
import json
with open("data.json", 'r') as f:
data = json.load(f)
df_from_file = pd.DataFrame(data)
- 从mysql中读取
当加载数据库类型的数据时,要先通过相关的连接模块(如pyodbc、pymysql)拿到游标(cursor),再结合pandas中的read_sql类获取数据,DataFrame列名会自动匹配sql中返回的列名,在处理数据上还是比较方便的。
import pandas as pd
import mysql.connector
# 连接mysql数据库
mydb = mysql.connector.connect(
host="localhost",
user="username",
password="password",
database="database"
)
# 创建游标
mycursor = mydb.cursor()
# 读取数据
sql = "SELECT * FROM yourtable"
mycursor.execute(sql)
mydf = pd.DataFrame(mycursor.fetchall(), columns=mycursor.column_names)
# 关闭游标和数据库连接
mycursor.close()
mydb.close()
2.2 数据访问
2.2.1 查看数据
直接以2.1.1节创建的数据为例
- 查看索引
>>> s.index
RangeIndex(start=0, stop=5, step=1)
>>> df.index
RangeIndex(start=0, stop=3, step=1)
- 查看数据集大小
>>> print(s.shape, s.size, df.shape, df.size)
(5,) 5 (3, 3) 9
shape返回数据集的行数/列数,返回类型为元组,size返回的事数据集的记录个数,即行×列的值,返回类型为整型。
- 查看部分数据 当数据量比较大时,往往需要只查看一部分数据,提供了head(n int)和tail(n int)函数,分别可查看数据集中的前n条和后n条数据,默认情况下n=5。
>>> print(s.head(1), s.tail(1), df.head(1), df.tail(1))
0 1
dtype: int32
4 5
dtype: int32
a b c
0 1 1 a
a b c
2 3 3 c
除了按顺序访问数组中的头和尾,还可以用sample()函数对数据集进行随机采样,sample默认返回一条记录,可以设置采样的记录数。
>>> s.sample()
a 1
dtype: int64
>>> s.sample(2)
a 1
b 2
dtype: int64
>>> df.sample()
a b c
2 3 3 c
>>> df.sample(2)
a b c
2 3 3 c
0 1 1 a
- 访问数据集中的某一个元素
要访问DataFrame中的元素,可以使用loc
方法或者iloc
方法,它们都返回一个Series对象。
-
-
loc
方法根据索引值访问DataFrame中的元素,它需要传入一个布尔数组,表示需要访问的行和列; -
iloc
方法根据行和列索引值访问DataFrame中的元素,它需要传入两个整数数组,表示行和列的索引值; -
另外
at
方法也可以实现访问其中的某一个元素,这里只介绍基本的用法,在今后的章节中会继续介绍。
-
>>> df.iloc[2,1]
'3'
>>> df.loc[2, 'b']
'3'
>>> df.at[2, 'b']
'3'
2.2.2 遍历
- 遍历Series
for index, value in data.iterrows():
print(index, value)
遍历Series还有其他方式,与DataFrame类似,将在下面的代码中说明。
- 遍历DataFrame
遍历DataFrame有几种方式:
# 方法1:用iterrows方法遍历每一行
for index, row in df.iterrows():
for column in df.columns:
print(f"Row {index}, Column {column}: {row[column]}")
# 在python3中,如果只是遍历行中的一列,可以用row.name来直接访问
# 方法2:用loc()遍历所有的单元格
for i in range(len(df.index)):
for j in range(len(df.columns)):
cell_value = df.iloc[i,j]
print(cell_value)
# 方法3:定义一个函数,用applymap()方法遍历
print_cell = lambda x: print(x)
df.applymap(print_cell)
# 方法4:用itertuples方法遍历
for row in df.itertuples():
index, *values = row
# 解包命名元组以获取索引和值列表
print(index, values)
值得说明的是,用pandas自带的迭代器iterrows和itertuples均可以实现DataFrame的遍历,itertuples()返回一个迭代器,其中每个元素都是命名元组(namedtuple),而iterrows()返回一个包含行索引和Pandas Series对象的元组,在加载速度上,itertuples()比iterrows()稍快。这是因为它使用Cython优化,在内部实现上更有效率。但对于小型数据集,两者差异不大,无需过分关注速度问题。