1、课堂笔记
TASK01-数据载入及初步观察.ipynb
TASK02-pandas基础.ipynb
TASK03-探索性数据分析.ipynb
2、Pandas笔记————Pandas 基础知识与语法
1、Pandas中的数据结构
1、DataFrame
二维数据结构,相当与表格。主体分数据和索引两部分。数据以==行(index)和列(Column)==的表格方式排列.
2、Series
一维数组,与Numpy中的数组(Array)相似数组中只允许存储相同的数据类型。
2、series结构基本操作
1、创建series
函数形参表:
Series(data=None, index=None, dtype=None, name=None, copy=False, fastpath=False)
data:存放数据的集合对象,可以是迭代对象、字典(版本>3.6)、常量(重复多次)
Index:指定索引或者自动生成的正整数索引值
dtype:指定数据类型
name:指定索引名称,
copy:是否对data进行复制,默认视图方式
Fastpath:这个参数在官方api文档中并没有给出具体解释,从源码来看应当是一种快速精简模式省略所有参数生成空series
1、由数组或列表建立
s1 = pd.Series(np.array([1,2,3,4]))
2、指定索引并默认创建
s2 = pd.Series(np.arange(3), index=['a', 'b', 'c'])
# Series对象的默认值分别为0,1,2。其索引分别为a,b,c
3、通过字典创建,同时指定名称和数据类型
s3 = pd.Series({'Tom': 95, 'Jack': 68, 'Alice': 83}, dtype=float, name='score')
索引 | Value |
---|---|
Tom | 95.0 |
Jack | 68.0 |
Alice | 83.0 |
3、DataFrame基本语法
1、创建DataFrame
DataFrame形参表
DataFrame(data=None, index=None, columns=None, dtype=None, copy =False)
1、通过现有的字典方式建立
data = {'Tom': [100, 88, 99], 'John': [89, 97, 100], 'Alice': [88, 99, 100]}
df1 = pd.DataFrame(data)
2、通过带Series对象的字典建立
s1 = pd.Series(np.array(['Tom', 'John', 'Alice', 'Jack']))
s2 = pd.Series(np.array([101, 606, 411, 310]))
temp_dic = {'Name': s1, 'Room No': s2}
df3=pd.DataFrame(temp_dic)
Name为第一个行索引,s1为第一列的数据;Room No为第二个行索引,s1为第二列的数据
3、通过现有的数组方式建立
data2 = np.array([[18, 19, 20], [2, 3, 4], [21, 22, 23]])
df2 = pd.DataFrame(data2)
# 此时行索引与列索引均为默认值0,1,2
4、显示设置行列标签,在 3 的基础上加了对行索引与列索引的赋值
score_arr = np.array([[95, 100, 99], [90, 80, 100], [85, 100, 100]])
score_df = pd.DataFrame(score_arr,columns=['语文', '数学', '英语'],index=['Tom', 'John', 'Alice'])
语文 | 数学 | 英语 | |
---|---|---|---|
Tom | 95 | 100 | 99 |
John | 90 | 80 | 100 |
Alice | 85 | 100 | 100 |
2、DataFrame常用属性
print(score_df.shape) # 获取DataFrame的形状大小
print(score_df.size) # 获取元素个数
score_df.info() # 获取DataFrame对象的基本信息
print(score_df.columns) # 获取列索引
print(score_df.index.tolist()) # 获取行索引
3、获取DataFrame中的数据
先创建一个DataFrame,用列表list构建数组array,再将数组转为DataFrame
employee_info_ls = [['001', '李明', 23, '吉林', 20000.00],
['002', '韩雷', 26, '湖北', 25000.00],
['003', '肖红', 30, '江西', 30000.00],
['004', '马克', 28, '上海', 21000.00]]
df = pd.DataFrame(np.array(employee_info_ls),
index=['one', 'two', 'three', 'four'],
columns=['ID', 'Name', 'Age', 'Address', 'Salary'])
ID | Name | Age | Adddress | Salary | |
---|---|---|---|---|---|
one | 001 | 李明 | 23 | 吉林 | 20000 |
two | 002 | 韩雷 | 26 | 湖北 | 25000 |
three | 003 | 肖红 | 30 | 江西 | 30000 |
four | 004 | 马克 | 28 | 上海 | 21000 |
1、通过列表索引获取数据
print(df['Name']) # 获取列索引对应的一个Series对象
print(df[['Name', 'Salary']]) # 多列索引返回DataFrame对象
one | 李明 |
---|---|
two | 韩雷 |
three | 肖红 |
four | 马克 |
Name | Salary | |
---|---|---|
one | 李明 | 20000 |
two | 韩雷 | 25000 |
three | 肖红 | 30000 |
four | 马克 | 21000 |
2、通过行序列号切片获取多行
print(df[1:4:2]) # 仅可通过行序号切片获取多行
3、利用Value属性获取
print(df.values)
print(df.values[0::2, 1::3])
# 得到的是列表
# [['李明' '20000.0']
# ['肖红' '30000.0']]
4、利用iloc属性获取
print(df.iloc[1]) # 获取单行,返回Series
print(df.iloc[[0, 1, 3]]) # 整数列表获取多行,返回DataFrame
print(df.iloc[1:4]) # 切片获取多行,返回DataFrame
print(df.iloc[:, 1]) # 获取单列,返回Series
print(df.iloc[:, [1, 3, 4]]) # 整数列表获取多列,返回DataFrame
print(df.iloc[:, 1:]) # 切片获取多列,返回DataFrame
print(df.iloc[0:3, 1:4]) # 行列序号切片,返回DataFrame
print(df.iloc[3, 4]) # 行列序号,返回具体值
Tips:
1、df.iloc支持布尔数组筛选
print(df.iloc[[True, False, True, False], [True]*3+[False]*2])
# 选取第一、第三行;选取前三列,舍去后两列
2、df.iloc支持函数
print(df.iloc[lambda x:x.index != 'three'])
# 选取索引x.index不等于three的数据
# Index:行索引,Columns:列索引
5、利用loc属性获取,用的最为广泛
print(df.loc['two']) # 获取单行,返回Series
print(df.loc[['one', 'two', 'four']]) # 列表获取多行,返回DataFrame
print(df.loc['two':'four']) # 切片获取多行,返回DataFrame,含终值
print(df.loc[:, 'Name']) # 获取单列,返回Series
print(df.loc[:, ['Name', 'Address', 'Salary']]) # 列表获取多列,返回DataFrame
print(df.loc[:, 'Name':]) # 切片获取多列,返回DataFrame
print(df.loc['one':'three', 'Name':'Address']) # 行列切片,返回DataFrame
print(df.loc['two', 'Salary']) # 行列标签,返回具体值
# 支持布尔数组筛选
print(df.loc[[True, False, True, False], [True]*3+[False]*2])
print(df.loc[df['Address'] == '湖北', 'Name':'Age'])
print(df.loc[df['Name'].str.startswith('肖')])
print(df.loc[df['Name'].isin(['李明', '马克'])])
# 数据筛选,重点掌握
print(df.loc[(df['Age'].astype(int) < 30) & (df['Salary'].astype(float) > 20000)])
print(df.loc[df['ID'].apply(lambda x:int(x[-1])%2 == 0)])
6、利用head()和tail()方法
print(df.head()) # 读前10行,不足10行读所有
print(df.tail(2)) # 读后两行
4、修改DataFrame中的数据
1、通过索引定位修改
df.loc['two', 'Salary'] = 30000.00 # 定位到单个元素,修改该元素的值
df.loc['four'] = np.nan # 修改整行为相同的值
df.loc['four'] = ['004', '韩雷雷', 40, '广州', 28000.00] # 列表修改整行
df.loc[:, 'Address'] = '湖北' # 修改整列为相同的值
df['Age'] = [25, 28, 21, 24] # 列表修改整列
# 修改数据块
df.loc[df['Age'] >= 25, ['Address','Salary']] = [['北京', 35000.0], ['上海', 35000.0]]
如果行索引和列索引不存在,则会在末尾增加新行
"""DataFrame增加行列"""
new_employee_info_ls = [['005', '刘春娇', 23, '广州', 35000.00],
['006', '李志明', 27, '广州', 35000.00]]
df.loc['five'] = new_employee_info_ls[0] # 行索引不存在,则末尾增加新行
df.loc['six'] = new_employee_info_ls[1]
df['Years'] = df['Age'].astype(int)-20 # 列索引不存在,则末尾增加新列
# insert在指定索引处插入列,索引必须为整数,且0<=索引<=len(columns)
df.insert(3, "Gender", ['男', '男', '女', '男', '女', '男'])
2、where,mask条件修改
函数的形参表
where(cond, other=nan, inplace=False, axis=None, level=None, errors='' raise', try_cast=False)
参数解释:
cond : 当cond为True时,保留原值。为 False,用other中的相应值代替。
inplace : bool, 默认为False 是否对数据进行原地操作。(使用较多)
axis : int, 默认为 None 如果需要的话,可选择对齐轴。
level : int, 默认为 None 如果需要的话,对齐级别。
Errors:{‘raise’, ‘ignore‘},是否允许引发异常
try_cast:尝试将结果转换回输入类型(如果可能)。
mask(cond, other=nan, inplace=False, axis=None, level=None, errors='raise', try_cast=NoDefault.no_default)
注意:
1、where()方法为:替换为False的那些行的值,保持True的行的值
2、where()与mask()方法是相反的。即mask,替换条件为True处的值
"""where与mask条件修改"""
# 非原地操作,生成新对象,Salary不大于32000,修改为32000
print(df['Salary'].where(df['Salary'].astype(float) > 32000, 32000.0))
# 原地操作,改变原DataFrame
df['Salary'].where(df['Salary'].astype(float) > 32000, 32000.0, inplace=True)
# 非原地操作,生成新对象,地址非湖北,Salary修改为30000
print(df['Salary'].mask(df['Address'] != '湖北', 30000.0))
# 原地操作,改变原DataFrame
df['Salary'].mask(df['Address'] != '湖北', 30000.0, inplace=True)
3、replace()替换指定值
df.replace(['北京', '上海'], '湖北', inplace=True) # 北京、上海替换成相同值湖北
print(df)
df.replace({'韩雷雷': '李雷雷', '广州': '深圳'}, inplace=True) # 按键值对,用值替换键
print(df)
df.replace('湖.+', '武汉', regex=True, inplace=True) # 正则匹配替换,
print(df)
5、数据排序
sort_values(by, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last’)
- by:指定列索引名(axis=0或’index’时);指定行索引值(axis=1或’columns’时)
- axis:缺省0或index ,按指定列中数据排序;1或 columns,按指定行中数据排序
- ascending:默认为升序排序;降序排序,ascending=False
- Inplace:是否用排序后的数据集替换原来的数据。默认为False,即不替换
- Kind:quicksort,mergesort,heapsort(快速排序,归并排序,堆排序)
- na_position:设定缺失值的显示位置{‘first’,‘last’}
df = pd.read_csv('score.csv')
print(df.sort_values('总分')) # 按总分列升序排列
scores_df=df.loc[:, 'C语言':'总分']
print(scores_df)
print(scores_df.sort_values(2, axis=1, ascending=False)) # 按索引为2的行降序排列
print(df['Python'].mean()) # 输出Python课程的平均分, 其他数据统计函数见下表
数据统计函数
方法名称 | 描述 |
---|---|
count( ) | 非空值数目 |
sum() | 求和 |
mean() | 平均值 |
median() | 中位数 |
min() | 最小值 |
max() | 最大值 |
std() | 样本标准差 |
6、分组统计与聚合
1、 分组统计
groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, **kwargs)
- by :接收映射、函数、标签或标签列表;用于确定聚合的组。
- axis : 接收 0/1;用于表示沿行(0)或列(1)分割。
- as_index:接收布尔值,默认Ture;Ture则返回以组标签为索引的对象,False则不以组标签为索引。
2、聚合
DataFrame.agg (func, axis=0, *args, **kwargs)
- func : 函数,用于聚合数据。
- axis : 默认 0。如果0或’ index ':应用函数到每一列。如果1或‘columns’:应用函数到每一行。
- args:要传递给func的位置参数。
- kwargs:要传递给func的关键字参数。
例子 :
姓名,学号,C语言,Java,Python,C#,Javascript,总分
罗明,0121701100510,95,96,85,63,91,430
朱佳,0121701100511,75,93,66,85,88,407
李思,0121701100513,86,76,96,93,67,418
郑君,0121701100514,88,98,76,90,89,441
王雪,0121701100515,99,96,91,88,86,460
df1 = pd.read_csv('score.csv')
# 返回总分的平均分
print(df1['总分'].agg('mean'))
# 返回两门课的总分、平均分和中位数
print(df1[['Python', 'Java']].agg(['sum', 'mean', 'median']))
# 应用agg()函数对分组结果汇总
# 求每位同学的平均分、最高分、最低分
print(df['分数'].groupby(df['姓名']).agg(['mean','max','min']))
# 求每门课的平均分、最高分、最低分
print(df['分数'].groupby(df['课程名']).agg(['mean','max','min']))