Pandas详解
一、 什么是Pandas?
Pandas的名称来自于面板数据(panel data),Pandas是一个强大的分析结构化数据的工具集,基于NumPy构建,提供了高级数据结构和数据操作工具,它是使Python成为强大而高效的数据分析环境的重要因素之一。Pandas有以下几个特点:
- 是一个强大的分析和操作大型结构化数据集所需的工具集
- 基础是NumPy,提供了高性能矩阵的运算
- 提供了大量能够快速便捷地处理数据的函数和方法
- 应用于数据挖掘,数据分析
- 提供数据清洗功能
二、为什么要学习pandas
numpy已经能够帮助我们处理数据,能够结合matplotlib解决我们数据分析的问题,那么pandas学习的目的在什么地方呢?
numpy虽能够处理数值型数据,但是很多时候数据除了数值之外,还需要处理字符串、时间序列等。比如:我们通过爬虫获取到了存储在数据库中的数据,所以,pandas出现了。
pandas官网:https://pandas.pydata.org/,首先先来认识pandas中的两个常用的类
- Series(一维数据)
- DataFrame(二维数据)
三、Series
3.1 Series的创建
Series是一个一维的结构,创建Series的语法:
pd.Series();
常用的几个参数:
- index,用于指定新的索引,例如pd.Series(arr1,index=[‘a’,‘b’,‘c’,‘d’,‘e’])以a,b,c,d,e作为行索引;
- dtype,用于指定元素的数据类型;
3.1.1 通过列表或者一维数组创建
import numpy as np import pandas as pd # 1.通过list创建一维数组 s1 = pd.Series([1, 2, 3, 4, 5]) print(s1) """ 0 1 1 2 2 3 3 4 4 5 dtype: int64 """ # 2.通过numpy一维数组创建,pandas一维数组 arr = np.arange(1, 6) s2 = pd.Series(arr) print(s2) """ 0 1 1 2 2 3 3 4 4 5 dtype: int32 """
3.1.2 通过字典创建
import pandas as pd dt = {'name': '范闲', 'age': 16, 'sex': '男'} s3 = pd.Series(dt) print(s3) """ name 范闲 age 16 sex 男 dtype: object """ # 通过字典创建数组的时候也可以指定索引,索引和字典键相同才有效,否则默认为 NaN s4 = pd.Series(dt,index=['name', 'age', 'sex', 'class']) print(s4) """ name 范闲 age 16 sex 男 class NaN dtype: object """
3.2 Series的基本用法
3.2.1.Series常用属性
Series的常用属性:
- shape 返回形状
- size 返回元素个数
- index 返回索引值
- values 返回值
- dtype 元素的类型
用法示例:
import pandas as pd # 创建pandas.Series对象 s = pd.Series(data=[1, 2, 3, 4, 'five'], index=['a', 'b', 'c', 'd', 'e']) print(s.shape) # 返回形状:(5,) print(s.dtype) # 返回元素类型:object print(s.size) # 返回元素个数: 5 print(s.index) # 返回索引值: Index(['a', 'b', 'c', 'd', 'e'], dtype='object') print(s.values) # 返回值: [1 2 3 4 'five']
3.2.2.索引取值
Series和DataFrame中的索引都是Index对象,索引对象不可变,保证了数据的安全。常见的Index种类:
- Index,索引
- Int64Index,整数索引
- MultiIndex,层级索引
- DatetimeIndex,时间戳类型
import pandas as pd dt = {'name': '范闲', 'age': 16, 'sex': '男'} s3 = pd.Series(dt) print(s3) """ name 范闲 age 16 sex 男 dtype: object """ # 根据索引取值,使用 s3[0] 按位置访问元素的方法已被弃用,使用会报提示 # print(s3[0]) # 现在推荐使用.iloc 方法按位置访问元素 print(s3.iloc[0]) # 范闲 print(s3.iloc[0:2]) """ name 范闲 age 16 dtype: object """
3.2.3.Series的常用方法:
⑴.head() 和 tail():
head(n): 返回前n个元素,默认是 5 个。tail(n): 返回后n个元素,默认是 5 个。
import pandas as pd s = pd.Series([1, 2, 3, 4, 5, 6]) print(s.head(3)) # 输出前 3 个元素 """ 0 1 1 2 2 3 dtype: int64 """ print(s.tail(3)) # 输出后 3 个元素 """ 3 4 4 5 5 6 dtype: int64 """
⑵.unique():
- 返回
Series中唯一值的数组。
import pandas as pd s2 = pd.Series([1, 2, 2, 3, 4, 4, 5]) print(s2.unique()) # 输出: [1 2 3 4 5]
⑶.isnull() 和 notnull():
isnull(): 检查Series中是否有缺失值,返回一个布尔Series。notnull(): 检查Series中是否没有缺失值,返回一个布尔Series。
import pandas as pd s = pd.Series([1, 2, None, 4, None]) print(s.isnull()) # 输出: [False False True False True] print(s.notnull()) # 输出: [ True True False True False]
⑷.add()、sub()、mul()、div():
这些方法用于按元素执行算术运算:
add(): 加法sub(): 减法mul(): 乘法div(): 除法
import pandas as pd s1 = pd.Series([1, 2, 3]) s2 = pd.Series([4, 5, 6]) print(s1.add(s2)) # 输出: [5, 7, 9] print(s1.sub(s2)) # 输出: [-3, -3, -3] print(s1.mul(s2)) # 输出: [4, 10, 18] print(s1.div(s2)) # 输出: [0.25, 0.4, 0.5]
3.2.4.Series的算术运算:
在 pandas.Series 中进行算术运算时,确保了索引一致的元素会进行算数运算,而对于不一致的索引,则会补空(NaN)。这种处理方式称为对齐(alignment)。举例来说,假设有两个 Series 对象 s1 和 s2:
import pandas as pd s1 = pd.Series([1, 2, 3], index=['a', 'b', 'c']) s2 = pd.Series([4, 5, 6], index=['b', 'c', 'd']) # 算术运算时,对齐索引进行操作,不一致的索引会补空(NaN) result = s1 + s2 print(result) """ result输出: a NaN b 6.0 c 8.0 d NaN dtype: float64 """
解释一下这个结果:
s1中的索引有'a', 'b', 'c',而s2中的索引有'b', 'c', 'd'。- 在进行加法运算时,对应的索引
'b'和'c'对应的元素分别是2和3,所以结果为2 + 4 = 6和3 + 5 = 8。 - 对于索引
'a'和'd',因为只存在于其中一个Series中,所以在结果中显示为NaN(空值)。
这种对齐操作使得 pandas.Series 在处理数据时非常灵活和方便,特别是在处理来自不同数据源或者部分缺失数据的情况下,能够保证结果的一致性和可靠性。
四、DataFrame
DataFrame 是一个【表格型】的数据结构。DataFrame 由按一定顺序排列的多列数据组成。设计初衷是将 Series 的使用场景从一维扩展到二维。在 DataFrame 中,每一列可以是不同的数据类型(例如整数、浮点数、字符串等),且每一列本质上是一个 Series。DataFrame 可以看作是共享同一个索引的多个 Series 组成的结构。
主要特点:
- 二维数据结构:
DataFrame是二维的,可以看作一个电子表格或 SQL 表。 - 按标签或整数索引:可以通过标签(列名)或整数索引访问数据。
- 不同数据类型的列:每一列可以是不同的数据类型。
4.1.DateFrame创建
4.1.1.字典类
import numpy as np import pandas as pd # 数组、列表或元组构成的字典构造dataframe # 注意:所有数组的长度必须相同 data = { "a": [1, 2, 3, 4, 5], "b": (5, 6, 7, 8, 9), "c": np.arange(9, 14) } # 构造dataframe df = pd.DataFrame(data) print(df) """ a b c 0 1 5 9 1 2 6 10 2 3 7 11 3 4 8 12 4 5 9 13 """
上面结果发现:DataFrame既有行索引,也有列索引。
- 行索引:index
- 列索引:columns
- 值:values
import numpy as np import pandas as pd # 数组、列表或元组构成的字典构造dataframe # 注意:所有数组的长度必须相同 data = { "a": [1, 2, 3, 4, 5], "b": (5, 6, 7, 8, 9), "c": np.arange(9, 14) } # 构造dataframe df = pd.DataFrame(data) """ a b c 0 1 5 9 1 2 6 10 2 3 7 11 3 4 8 12 4 5 9 13 """ # index属性查看行索引 print(df.index) # RangeIndex(start=0, stop=5, step=1) # columns属性查看列索引 print(df.columns) # Index(['a', 'b', 'c'], dtype='object') # values属性查看值 print(df.values) """ [[ 1 5 9] [ 2 6 10] [ 3 7 11] [ 4 8 12] [ 5 9 13]] """ # 指定index df2 = pd.DataFrame(data, index=['A', 'B', 'C', 'D', 'E']) print(df2) """ a b c A 1 5 9 B 2 6 10 C 3 7 11 D 4 8 12 E 5 9 13 """
4.1.2.列表类
import numpy as np import pandas as pd # Series构成的字典构造dataframe dt = pd.DataFrame({'a': pd.Series(np.arange(3)), 'b': pd.Series(np.arange(3, 5))}) print(dt) """ a b 0 0 3.0 1 1 4.0 2 2 NaN """
4.2.DataFrame的基本用法
4.2.1.T转置
在 pandas 中,.T 属性可以用来转置一个 DataFrame。转置操作会将行和列进行互换。
import numpy as np import pandas as pd pd1 = pd.DataFrame(np.arange(9).reshape(3, 3), index=['a', 'b', 'c'], columns=['A', 'B', 'C']) """ A B C a 0 1 2 b 3 4 5 c 6 7 8 """ print("*****************T转置*****************") print(pd1.T) """ a b c A 0 3 6 B 1 4 7 C 2 5 8 """
可以看到,转置后的 DataFrame 中,原来的行变成了列,原来的列变成了行。注意事项:
- 如果 DataFrame 的列和行标签都是唯一的,转置操作是非常直观的。
- 对于大型 DataFrame,转置操作可能会消耗较多内存和计算资源,因此需要根据实际情况评估性能。
4.2.2.通过列索引获取列数据(Series类型)
在 pandas 中,可以通过列索引来获取特定列的数据,返回的结果是一个 Series 类型。可以使用多种方法来实现这一点,包括使用中括号 []、点符号 . 和 loc/iloc 属性。下面是一些示例:
import numpy as np import pandas as pd pd1 = pd.DataFrame(np.arange(9).reshape(3, 3), index=['a', 'b', 'c'], columns=['A', 'B', 'C']) """ A B C a 0 1 2 b 3 4 5 c 6 7 8 """ # 方法 1: 使用中括号 [] column_A = pd1['A'] print(column_A) """ a 0 b 3 c 6 Name: A, dtype: int32 """ print(type(column_A)) # <class 'pandas.core.series.Series'> # 方法 2: 使用点符号 . # 获取列 'B' 的数据 column_B = pd1.B print(column_B) """ a 1 b 4 c 7 Name: B, dtype: int32 """ print(type(column_B)) # <class 'pandas.core.series.Series'> # 方法 3: 使用 loc 属性(上面index设置的索引就可以通过loc取值) # 获取列 'C' 的数据 column_C = pd1.loc[:, 'C'] print(column_C) """ a 2 b 5 c 8 Name: C, dtype: int32 """ print(type(column_C)) # <class 'pandas.core.series.Series'> # 方法 4: 使用 iloc 属性 (通过列的索引位置) # 获取第一列 (索引位置为 0) 的数据 column_0 = pd1.iloc[0] print(column_0) """ A 0 B 1 C 2 Name: a, dtype: int32 """ print(type(column_0)) # <class 'pandas.core.series.Series'>
在 pandas 中,使用 loc 属性时,冒号 : 有选择行或列的范围的作用。具体来说,冒号可以用于选择整个行或列。在 DataFrame 中,loc 属性的基本语法是 df.loc[row_selection, column_selection]。冒号 : 的作用
- 在行选择中使用冒号
:可以选择所有行。 - 在列选择中使用冒号
:可以选择所有列。
4.2.3.增加列数据
在 pandas 中,可以通过多种方法向 DataFrame 中添加新列。下面是一些常用的方法:
方法 1: 直接赋值
通过直接赋值的方式增加新列:
import numpy as np import pandas as pd pd1 = pd.DataFrame(np.arange(9).reshape(3, 3), index=['a', 'b', 'c'], columns=['A', 'B', 'C']) """ A B C a 0 1 2 b 3 4 5 c 6 7 8 """ # 方法 1: 直接赋值 pd1['D'] = [9, 10, 11] # 输出增加新列后的 DataFrame print(pd1) """ A B C D a 0 1 2 9 b 3 4 5 10 c 6 7 8 11 """
方法 2: 使用 assign 方法
通过 assign 方法增加新列:
import numpy as np import pandas as pd pd1 = pd.DataFrame(np.arange(9).reshape(3, 3), index=['a', 'b', 'c'], columns=['A', 'B', 'C']) """ A B C a 0 1 2 b 3 4 5 c 6 7 8 """ # 增加新列 'E' 并创建新的 DataFrame pd2 = pd1.assign(E=[12, 13, 14]) # 输出增加新列后的 DataFrame print(pd2) """ A B C E a 0 1 2 12 b 3 4 5 13 c 6 7 8 14 """
方法 3: 使用 insert 方法
通过 insert 方法在特定位置插入新列:
import numpy as np import pandas as pd pd1 = pd.DataFrame(np.arange(9).reshape(3, 3), index=['a', 'b', 'c'], columns=['A', 'B', 'C']) """ A B C a 0 1 2 b 3 4 5 c 6 7 8 """ # 在索引位置 1 处插入新列 'F' pd1.insert(1, "F", [12, 13, 14]) # 输出增加新列后的 DataFrame print(pd1) """ A F B C a 0 12 1 2 b 3 13 4 5 c 6 14 7 8 """
方法 4: 根据现有列计算新列
根据现有列的数据计算新列:
import numpy as np import pandas as pd pd1 = pd.DataFrame(np.arange(9).reshape(3, 3), index=['a', 'b', 'c'], columns=['A', 'B', 'C']) """ A B C a 0 1 2 b 3 4 5 c 6 7 8 """ # 计算列 'G',其值为列 'A' 和列 'B' 之和 pd1['G'] = pd1['A'] + pd1['B'] # 输出增加新列后的 DataFrame print(pd1) """ A B C G a 0 1 2 1 b 3 4 5 7 c 6 7 8 13 """
4.2.4.删除列
在 pandas 中,可以通过多种方法删除 DataFrame 中的列。下面介绍几种常用的方法:
方法 1: 使用 drop 方法
使用 drop 方法删除列:
import numpy as np import pandas as pd pd1 = pd.DataFrame(np.arange(9).reshape(3, 3), index=['a', 'b', 'c'], columns=['A', 'B', 'C']) """ A B C a 0 1 2 b 3 4 5 c 6 7 8 """ # 删除列 'B' pd1_drop = pd1.drop(columns=['B']) print(pd1_drop) """ A C a 0 2 b 3 5 c 6 8 """
方法 2: 使用 del 关键字
使用 del 关键字删除列:
import numpy as np import pandas as pd pd1 = pd.DataFrame(np.arange(9).reshape(3, 3), index=['a', 'b', 'c'], columns=['A', 'B', 'C']) """ A B C a 0 1 2 b 3 4 5 c 6 7 8 """ # 使用 del 删除列 'C' del pd1['C'] print(pd1) """ A B a 0 1 b 3 4 c 6 7 """
方法 3: 使用 pop 方法
使用 pop 方法删除并返回指定列:
import numpy as np import pandas as pd pd1 = pd.DataFrame(np.arange(9).reshape(3, 3), index=['a', 'b', 'c'], columns=['A', 'B', 'C']) """ A B C a 0 1 2 b 3 4 5 c 6 7 8 """ # 使用 pop 删除并返回列 'A' column_A = pd1.pop('A') print(column_A) """ a 0 b 3 c 6 Name: A, dtype: int32 """ print(pd1) """ B C a 1 2 b 4 5 c 7 8 """
方法 4: 使用索引方式
直接使用索引方式删除列:
import numpy as np import pandas as pd pd1 = pd.DataFrame(np.arange(9).reshape(3, 3), index=['a', 'b', 'c'], columns=['A', 'B', 'C']) """ A B C a 0 1 2 b 3 4 5 c 6 7 8 """ # 使用索引方式删除列 'B' pd1 = pd1.drop(columns=['B']) print(pd1) """ A C a 0 2 b 3 5 c 6 8 """
详细说明
- 使用
drop方法:pd1.drop(columns=['B'])删除列 'B' 并返回一个新的 DataFrame,原始 DataFrame 不变。 - 使用
del关键字:del pd1['C']直接从原始 DataFrame 中删除列 'C',原地操作,不返回新的 DataFrame。 - 使用
pop方法:pd1.pop('A')删除并返回列 'A',原地操作,同时返回被删除的列。 - 直接使用索引方式:
pd1 = pd1.drop(columns=['B'])同样是使用drop方法删除列 'B',但这里将结果重新赋值给原始 DataFrame。
4.3.DataFrame常用的属性
values、columns、index、shape用法和series差不多直接调用即可
values:返回 DataFrame 的数据部分,二维 numpy 数组。columns:返回 DataFrame 的列标签,类型为 Index。index:返回 DataFrame 的行索引标签,类型为 Index。shape:返回 DataFrame 的维度信息,即行数和列数的元组。
import numpy as np import pandas as pd pd1 = pd.DataFrame(np.arange(9).reshape(3, 3), index=['a', 'b', 'c'], columns=['A', 'B', 'C']) """ A B C a 0 1 2 b 3 4 5 c 6 7 8 """ # 使用values:返回 DataFrame 的数据部分,二维 numpy 数组。 print(pd1.values) """ [[0 1 2] [3 4 5] [6 7 8]] """ # columns 属性返回 DataFrame 的列标签(列名)。 print(pd1.columns) # Index(['A', 'B', 'C'], dtype='object') # index 属性返回 DataFrame 的行索引标签。 print(pd1.index) # Index(['a', 'b', 'c'], dtype='object') # shape 属性返回 DataFrame 的维度信息,即行数和列数。 print(pd1.shape) # (3, 3)
4.4.DataFrame索引操作
4.4.1.对列进行索引
import numpy as np import pandas as pd pd1 = pd.DataFrame(data=np.random.randint(50, 100, size=(3, 4)), columns=['a', 'b', 'c', 'd']) print(pd1) """ a b c d 0 55 73 64 62 1 67 75 60 54 2 71 95 87 51 """ # 取单列,如果pd1有显示的索引,通过索引机制取行或者列的时候只可以使用显示索引 print(pd1['a']) """ 0 55 1 67 2 71 Name: a, dtype: int32 """ # 取多列 print(pd1[['a', 'c']]) """ a c 0 55 64 1 67 60 2 71 87 """
4.4.2.对行进行索引和对元素进行索引
- iloc:通过隐式索引取行
- loc:通过显示索引取行
import numpy as np import pandas as pd pd1 = pd.DataFrame(data=np.random.randint(50, 100, size=(3, 4)), columns=['a', 'b', 'c', 'd']) print(pd1) """ a b c d 0 82 66 51 80 1 78 53 74 64 2 89 71 82 97 """ # 取单行,这里的pd1行索引为隐式索引(没有指定索引),用iloc或loc都可以 print(pd1.iloc[0]) """ a 82 b 66 c 51 d 80 Name: 0, dtype: int32 """ # 取多行 print(pd1.iloc[[0, 2]]) # 取第0行和第2行 """ a b c d 0 82 66 51 80 2 89 71 82 97 """ # 取单个元素 print(pd1.iloc[0, 2]) # 取第0行第2列的元素 51 # 取多个元素 print(pd1.iloc[[0, 2], 2]) # 取第0行和第2行的第二列元素 """ 0 51 2 82 Name: c, dtype: int32 """
4.5.DataFrame的切片操作
import numpy as np import pandas as pd pd1 = pd.DataFrame(data=np.random.randint(50, 100, size=(6, 4)), columns=['a', 'b', 'c', 'd']) print(pd1) """ a b c d 0 95 57 67 62 1 58 81 59 79 2 81 80 66 69 3 51 73 69 50 4 54 75 58 60 5 78 56 96 63 """ # 切行(切取索引0-3行下面两种方式结果相同) print(pd1[0:4]) print(pd1.iloc[0:4]) """ a b c d 0 95 57 67 62 1 58 81 59 79 2 81 80 66 69 3 51 73 69 50 """ # 切列 print(pd1.iloc[:, 0:2]) """ a b 0 95 57 1 58 81 2 81 80 3 51 73 4 54 75 5 78 56 """
DataFrame索引和切片操作:
⑴.索引:
df[col]:取列
df.loc[index]:取行
df.iloc[index,col]:取元素
⑵.切片:
df[index1:index3]:切行
df.iloc[:,col1:col3]:切列

浙公网安备 33010602011771号