pandas数据分析和plot画布的使用

pandas数据分析和plot画布的使用

在我们实际生活中充满着大量的数据,那么这些数据需要怎么去筛选呢?python中的pandas给了我们非常强大的批量管理功能,同时plot画布也可以便于我们将数据可视化。

pandas

pandas中包括Series和DataFrame

pandas 是 Python 中一个非常流行的数据分析库,它提供了高效、灵活的数据结构和工具,尤其是 DataFrameSeries 两种数据结构,广泛用于数据清洗、处理、分析和建模。

pandas :是一个 Python 的库(包),它的名字源自“panel data”的缩写。pandas 提供了高效的数据结构和数据操作工具,特别是处理表格数据(类似数据库表或 Excel 表格)和时间序列数据。它能够让用户轻松地加载、清理、处理、变换、分析和可视化数据。

1
import pandas as pd

Series:是 pandas 中的一种数据结构,类似于一维数组(numpy.ndarray),但它具备更多功能。每个 Series 由一组数据和一个与之相关的索引组成,因此它不仅仅是一个简单的列表,还可以通过标签来访问元素。Seriespandas 中最基础的数据类型。

  • 一维数据结构。
  • 包含数据(可以是任何类型,如数字、字符串、日期等)和索引。
  • 索引为数据提供了标签,可以通过标签进行定位和访问。

示例:

1
2
3
4
# 创建一个 Series 对象
s = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])

print(s)

输出:

1
2
3
4
b    20
c 30
d 40
dtype: int64

在这个例子中,s 是一个 Series,它包含四个数据点和相应的索引标签。

Series 的内部结构:

  • 数据:[10, 20, 30, 40]
  • 索引:['a', 'b', 'c', 'd']

DataFrame:是 pandas 中最强大和常用的数据结构,它是一个二维的表格结构,类似于数据库中的表、Excel 表格或 SQL 查询的结果集。DataFrame 可以被看作是多个 Series 的组合,每个 Series 对应一个列,因此每个列都可以有自己的数据类型。

特点:

  • 二维数据结构(表格形式)。
  • 每列是一个 Series,每行也有索引。
  • 行和列都有标签,可以通过行标签和列标签进行数据访问。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
import pandas as pd

# 创建一个 DataFrame 对象
data = {
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]
}

df = pd.DataFrame(data)

print(df)

输出:

1
2
3
4
   A  B  C
0 1 4 7
1 2 5 8
2 3 6 9

在这个例子中,df 是一个 DataFrame,它包含三列:ABC,每列的数据是一个 Series

pandasSeriesDataFrame 之间的关系

  1. pandas 是一个库,提供了操作和分析数据的功能。
    • pandas 包含了 SeriesDataFrame 这两种核心的数据结构。
  2. Seriespandas 中的一维数据结构,它可以看作是 DataFrame 的一列。
    • Series 适用于一维数据的存储和操作,它有一个一维的数组结构和一个与之相关的索引(标签)。
  3. DataFramepandas 中的二维数据结构,由多个 Series 组成。
    • 每个 DataFrame 由多个列(Series)组成,行和列都可以有标签(索引和列名)。

数据结构的层级关系:

  • pandas 是整个库。
  • Seriespandas 提供的基本数据结构之一,表示一维数据。
  • DataFramepandas 中的二维数据结构,由多个 Series 组成。

以上我们搞清楚了pandas、Series、DataFrame之间的关系,接下来我们看看如何使用他们。

读取

将csv文件读取成dataframe对象:

1
2
import pandas as pd
df_citygdp = pd.read_csv('city.csv', index_col=0, header=0)

index_col=0表示将第一列作为行索引,header=0表示将第一行作为列索引。

同样的,如果是excel文件:

1
2
import pandas as pd
df_zpcjd = pd.read_excel('综评成绩单.xlsx', index_col=[1, 2])

index_col=[0,1]表示将第二和第三列作为行索引。

注意:

  • csv文件:是纯文本文件,每一行代表一条记录,记录中的字段由逗号或其他分隔符(如制表符、分号等)分隔。
  • xlsx文件:是 Excel 的标准文件格式,基于 XML(可扩展标记语言)。它使用压缩的二进制格式存储数据,并可以包含多个工作表(Sheet)。

读出来的表如上图

或者直接手动创建:

1
2
data = {'A': [1, 2, 3, 4, 5], 'B': [10, 20, 30, 40, 50]}
df = pd.DataFrame(data)

输出:

1
2
3
4
5
6
   A   B
0 1 10
1 2 20
2 3 30
3 4 40
4 5 50

筛选

列筛选

假如:我们要筛选出”20经贸类4”的作业、实验、出勤、期末情况。

首先我们如果我们按字典的输入方式,输入:

1
df_zpcjd['班级']

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
学号            姓名 
180110840516 梁家豪 18会计2
190110920132 石杨 19经贸1
200110920423 李润 20财会类3
200110920426 林小康 20财会类3
200110810629 吾佳悦 20财税类6
200110920415 胡绮 20金融类2
200110920401 陈思慧 20经贸类4
200110920402 陈特 20经贸类4
200110920404 陈雨廷 20经贸类4
200110920405 陈雨薇 20经贸类4
200110920406 戴佳妮 20经贸类4
200110920407 丁子厚 20经贸类4
200110920408 董睿滢 20经贸类4
200110920409 董欣桦 20经贸类4
200110920410 符嘉瑞 20经贸类4
200110920411 傅敬轩 20经贸类4
200110920412 巩静雯 20经贸类4
200110920413 洪旭辉 20经贸类4
200110920414 侯家馨 20经贸类4
200110920416 黄伟伟 20经贸类4
200110920417 黄卓佳 20经贸类4
200110920418 姜梦柯 20经贸类4
200110920419 荆国隆 20经贸类4
200110920420 赖砚儿 20经贸类4
...

可以看到输出了一整列只有班级的值,因此我们只用直接将“班级“进行比较,无需再用for循环,就可以直接输出所有”20经贸类4“班级的信息:

1
2
df_20_jm4 = df_zpcjd[df_zpcjd['班级'] == '20经贸类4']
print(df_20_jm4)

输出为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
					 班级      作业 实验 出勤 期末
学号 姓名
200110920401 陈思慧 20经贸类4 90 95 95 84
200110920402 陈特 20经贸类4 65 65 65 72
200110920404 陈雨廷 20经贸类4 90 85 85 44
200110920405 陈雨薇 20经贸类4 90 95 95 83
200110920406 戴佳妮 20经贸类4 90 90 90 76
200110920407 丁子厚 20经贸类4 85 90 90 57
200110920408 董睿滢 20经贸类4 97 90 90 51
200110920409 董欣桦 20经贸类4 70 80 80 66
200110920410 符嘉瑞 20经贸类4 90 90 90 68
200110920411 傅敬轩 20经贸类4 70 80 80 72
200110920412 巩静雯 20经贸类4 97 90 90 76
200110920413 洪旭辉 20经贸类4 90 95 95 85
200110920414 侯家馨 20经贸类4 92 85 85 48
200110920416 黄伟伟 20经贸类4 95 90 90 73
200110920417 黄卓佳 20经贸类4 95 90 90 75
200110920418 姜梦柯 20经贸类4 96 90 90 78
200110920419 荆国隆 20经贸类4 96 90 90 55
200110920420 赖砚儿 20经贸类4 96 95 95 84
200110920421 李鲍华 20经贸类4 95 90 90 57
200110920422 李慧婷 20经贸类4 90 90 90 67
200110920424 李奕璁 20经贸类4 96 95 95 81
200110920425 李雨萍 20经贸类4 93 90 90 77
...

由次可以看到,进行直接的比较就可以筛选出想要的值。

最后再将想要的值筛选出所需列即可(如果由多个列,直接用列表即可)。

完整如下:

1
2
3
df_20_jm4 = df_zpcjd[df_zpcjd['班级'] == '20经贸类4'] 
df_selected = df_20_jm4[['作业', '实验', '出勤', '期末']]
print(df_selected)
行筛选

这里我们就可以讲到loc方法,loc方法可以帮我们精准定位我们需要的信息。

1
df.loc[行索引, 列索引]

比如我想要筛选出“陈思慧”这一行,我们就可以直接输入:

1
df_zpcjd.loc[(200110920401, '陈思慧')] #由于是多索引,我们要把索引值完整的加上,即包括学号

输出:

1
2
3
4
5
6
班级    20经贸类4
作业 90
实验 95
出勤 95
期末 84
Name: (200110920401, 陈思慧), dtype: object

筛选期末成绩小于40或者综合成绩小于60的:

1
df_bukao=df_zpcjd[(df_zpcjd["期末"]<40) | (df_zpcjd["综合成绩"]<60)]

注意或是”|”还有两项之间要用括号分隔。

清洗

行删除

删除行时,通常使用 drop() 方法并指定 axis=0(行的方向),可以通过行标签来删除。

1
df = df.drop('行标签', axis=0)
列删除
1
df = df.drop('列名', axis=1)
删除重复列
1
df.loc[:, df_citygdp.nunique() > 1]

这里的用了loc中的nunique方法。这个方法会返回每一列中唯一值的数量。结果是一个包含每列唯一值数量的 Series

1
df.dropna(axis=1)

这个dropna方法可以删除所有包含NaN的列(或行)

Series保存

保存一个新系列,一行一列,只用Series即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
max_score = df_zpcjd['综合成绩'].max()  # 最大值
min_score = df_zpcjd['综合成绩'].min() # 最小值
mean_score = df_zpcjd['综合成绩'].mean() # 平均值
std_score = df_zpcjd['综合成绩'].std() # 标准差
var_score = df_zpcjd['综合成绩'].var() # 方差

sr_cjtj = pd.Series({
'最大值': max_score,
'最小值': min_score,
'平均值': mean_score,
'标准差': std_score,
'方差': var_score
})
print(sr_cjtj)

输出:

1
2
3
4
5
6
最大值     95.650000
最小值 38.400000
平均值 75.136170
标准差 11.516603
方差 132.632142
dtype: float64

时间计算

时间计算需要用到pandas自带的to_datetime方法:

1
2
df_order['use_start_time'] = pd.to_datetime(df_order['use_start_time'], errors='coerce')
df_order['lock_time'] = pd.to_datetime(df_order['lock_time'], errors='coerce')

设置 errors='coerce',如果无法转换为日期时间,则将该值设置为 NaT(Not a Time)。

如果需要计算时间差值:

1
df_order['meal_duration'] = (df_order['lock_time'] - df_order['use_start_time']).dt.total_seconds()/60

注意这里两个时间相减返回的是一个timedelta对象,因此可以用dt中的total_seconds方法返回差了几秒。然而如果你使用:

1
df_order['use_start_time'].dt.total_seconds()

则报错,因为df_order[‘use_start_time’]为datetime对象。

如果你要提取出日期,则这么写:

1
df_order['use_start_date'] = df_order['use_start_time'].dt.date

这个dt是datetime,用的是dt中的date方法。

groupby

按组分别计算,比如我需要计算每天的平均使用时间(题目是用餐时间),就可以以日期为组,计算出的时间差为值计算平均值:

1
2
#df.groupby('组名')['值']
daily_avg_meal_time = df_order.groupby('use_start_date')['meal_duration'].mean()

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use_start_date
2016-08-01 10.473810
2016-08-02 11.563889
2016-08-03 13.116667
2016-08-04 13.465385
2016-08-05 1109.650000
2016-08-06 9.141315
2016-08-07 9.054688
2016-08-08 10.751042
2016-08-09 9.555556
2016-08-10 12.171429
2016-08-11 10.852222
2016-08-12 693.875439
2016-08-13 10.120707

plot画布

首先我们要导入文件:

1
2
3
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False #中文输入

我们约定俗成简写成plt。

下面两行是为了能够有中文输入,因为原本这里是不支持中文的。

我们要创建要一个画布,我们主要要有一下部件:

  • 函数类型
  • 函数数据
  • 标题
  • x轴标签、y轴标签
  • x轴坐标数据、y轴坐标数据

这几个都是独立开来的,所以我们只需要的是叠加,就能完成画布制作。

折线图

1
2
3
4
5
6
7
8
9
p1 = plt.figure(figsize=(8,20)) #父画布
p1.add_subplot(3,1,1) #三分之一的画布占用,下面的plt都属指这个subplot,而且都是并行执行的。
plt.plot(range(20),ar_shuju[-3:-23:-1,-2],color='r') #plot(x轴数据,y轴数据,线条颜色)
plt.plot(range(20),ar_shuju[-3:-23:-1,-1],color='y') #plot是折线图
plt.title('1996-2015人口变化趋势') #标题
plt.xlabel('年份') #x轴标签
plt.ylabel('人口(万人)') #y轴标签
plt.xticks(range(20),ar_shuju[-3:-23:-1,0],rotation=45) #x轴数据名称(个数,数据,倾斜度)
plt.legend(['城镇人口','乡村人口']) #线的名称

这个例子中range(20)表示x轴的数据,ar_shuju[-3:-23:-1,-2]表示y轴数据。

饼状图

1
2
3
4
p1.add_subplot(3,1,3)
explodel = [0.01,0.01]
plt.pie(ar_shuju[0,4:6],explode=explodel,labels=['城镇人口','乡村人口'],autopct='%5.2f%%')
plt.title('2015年末城乡人口比例图')

条状图

1
plt.bar([x轴数据...],[y轴数据...])

道理类似。


pandas数据分析和plot画布的使用
https://bayeeaa.github.io/2024/11/23/pandas数据分析和plot画布的使用/
Author
Ye
Posted on
November 23, 2024
Licensed under