[数据分析笔记] Pandas知识合集 1 - 15

文章目录

1.Pandas数据读取

1.1 读取csv

pd.read_csv

查看数据的头尾
df.head(5)
df.tail(5)

查看数据的形状,返回(行数、列数)
df.shape

查看列名列表
df.columns

查看索引列
df.index

查看每列的数据类型
df.dtypes

1.2 读取txt

df = pd.read_csv(fpath, sep="\t", header=None, names=['a', 'b', 'c'])

1.3 读取excel文件

df = pd.read_excel(fpath)

1.4 读取MySQL数据库

import pymysql
conn = pymysql.connect(
		host = '127.0.0.1',
		user = 'root',
		password = '123',
		database = 'test',
		charset = 'utf8'
	)

df = pd.read_sql("select * from table", con=conn)

2.Pandas数据结构

2.1 Series

(1)仅有数据列表可产生最简单的Series

df = pd.Series([1, '1', 5.1, 6])

获取索引
df.index

获取数据
df.value

(2)创建一个具有标签索引的Series

df = pd.Series([1, '1', 5.1, 6], index=['a', 'b', 'c', 'd'])

(3)使用python字典创建Series

data = {'A': 1, 'B': 2, 'C': 3}
df = pd.Series(data)

(4)根据标签访问数据

df['A']

df[['A', 'B']]

2.2 DataFrame

(1)根据多个字典序列创建DataFrame

data = {
		'A': [1, 2, 3, 4],
		'B': [4, 5, 6, 7],
		'C': [8, 9, 10, 11]
	}
df = pd.DataFrame(data)

(2)从DataFrame中查询出Series

查询一列
df['A']

查询多列
df[['A', 'B']]

查询一行
df.loc[1]

查询多行
df.loc[1:3]

3.Pandas查询数据

3.1 读取数据

读取数据
df = pd.read_csv(fpath)

设置索引为日期
df.set_index('date', inplace=True)

替换温度的后缀℃——————5℃————>5
df.loc[:, 'temperature'] = df['temperature'].str.replace('℃', '').astype('int32')

3.2 使用单个Label值查询数据

得到单个值
df.loc['2020-05-01', 'temperature']

得到一个Series
df.loc['2020-05-01', ['temperature', 'tempe']]

3.3 使用值列表批量查询

得到Series
df.loc[['2020-05-01', '2020-05-02'], 'temperature']

得到DataFrame
df.loc[['2020-05-01', '2020-05-02'], ['temperature', 'tempe']]

3.4 使用数值区间进行范围查询

区间包含开始和结束

行index按区间
df.loc['2020-05-01': '2020-05-06', 'temperature']

列index按区间
df.loc['2020-05-01', 'temperature': 'A']

行和列都按区间
df.loc['2020-05-01': '2020-05-06', 'temperature': 'A']

3.5 使用条件表达式查询

查询温度低于10度的列表
df.loc['temperature'<10, :]

复杂条件查询
组合条件用&符号合并,每个条件判断都得带括号
查询最高温度小于30度,并且最低温度大于15度,并且是晴天,并且天气为优的数据
df.loc[(df['A']<=30) & (df['B']>=15) & (df['C']=='晴天') & (df['D']=='优'), :]

3.6 调用函数查询

直接写lambda表达式
df.loc[lambda df : (df['A']<=30) & (df['B']>=15), :]

编写自己的函数,查询9月份,空气质量好的数据
def query_data(df):
	return df.index.str.startswith('2020-09') & (df['A']=='优')

df.loc[query_data, :]

4.Pandas新增数据列

4.1 直接赋值

计算温差,新增一列
df.loc[:, 'E'] = df['A'] - df['B']

4.2 apply方法

实例:添加一列温度类型
1.如果最高温度大于30度就是高温
2.如果低于-10度就是低温
3.否则是常温

def get_type(x):
	if x['A'] > 30:
		return 'High'
	elif x['B'] < -10:
		return 'Low'
	else:
		return 'Normal'

需要设置axis=1,这里Series的index是columns,如果axis=0就是index
df.loc[:, 'F'] = df.apply(get_type, axis=1)

查看温度类型的计数
df['F'].value_counts()

4.3 df.assign方法

实例:将温度从摄氏度变为华氏度
可以同时添加多个新的列
df.assign(
	E = lambda x : x['A'] * 9 / 5 + 32,
	F = lambda x : x['B'] * 9 / 5 + 32
)

4.4 按条件选择分组分别赋值

按条件先选择数据,然后对这部分数据赋值新列
实例:高低温差大于10度,则认为温差大

先创建空列
df['E'] = ''
df.loc[df['A']-df['B']>10, 'E'] = '温差大'
df.loc[df['A']-df['B']<=10, 'E'] = '温差正常'

5.Pandas数据统计函数

5.1 汇总类统计

提取所有数字列统计结果
df.describe()

查看单个Series的数据
df['A'].mean()

5.2 唯一去重和按值计数

唯一性去重
一般不用于数值列,而是枚举、分类列
df['A'].unique()

按值计数
df['A'].value_counts()

5.3 相关系数和协方差

协方差:衡量同向反向程度,如果协方差为正,说明X,Y同向变化,协方差越大说明同向程度越高;如果协方差为负,说明X,Y反向运动,协方差越小说明反向程度越高。

协方差矩阵
df.cov()

相关系数矩阵
df.corr()

df['A'].corr(df['B'])

6.Pandas数据缺失值处理

在这里插入图片描述
原始EXCEL文件
在这里插入图片描述
(1)读取EXCEL时,忽略前几个空行

df = pd.read_excel(fpath, skiprows=2)

(2)检测空值

df.isnull()

df.notnull()

筛选没有空分数的所有行
df.loc[df['分数'].notnull(), :]

(3)删除全是空值的列

df.dropna(axis='columns', how='all', inplace=True)

(4)删除全是空值的行

df.dropna(axis='index', how='all', inplace=True)

(5)将分数列为空的填充为0分

df.fillna({'分数': 0}, inplace=True)

等同于
df['分数'].fillna(0, inplace=True)

(6)将姓名的缺失值填充

使用前面的有效值填充,用ffill:forward fill

df.loc[:, '姓名'] = df['姓名'].fillna(method='ffill')

(7)将清洗好的EXCEL保存

df.to_excel(fpath2, index=False)

7.Pandas报警、原因、解决

8.Pandas对数据进行排序

在这里插入图片描述

8.1 Series排序

升序排序
df['A'].sort_values()
.
降序排序
ad['A'].sort_values(ascending=False)

8.2 DataFrame的排序

单列排序
df.sort_values(by='A')
df.sort_values(by='B', ascending=False)

多列排序
df.sort_values(by=['A', 'B'])
df.sort_values(by=['A', 'B'], ascending=False)
分别指定升序和降序
df.sort_values(by=['A', 'B'], ascending=[True, False])

9.Pandas字符串处理

在这里插入图片描述

9.1 获取Series的str属性,使用各种字符串处理函数

df['A'].str

字符串替换
df['A'].str.replace('C', '')

判断是不是数字
df['A'].str.isnumeric()

9.2 使用str的startswith、contains等得到bool的Series可以做条件查询

condition = df['A'].str.startswith('2020-5-1')

df[condition].head()

9.3 需要多次str处理的链式操作

怎样提取202005这样的数字月份?
1.先将日期2020-05-01替换成20200501的形式
2.提取月份字符串202005

df['A'].str.replace('-', '')

df['A'].str.replace('-', '').str.slice(0, 6)

df['A'].str.replace('-', '').str[0:6]

9.4 使用正则表达式处理

添加新列
def get_date(x):
	year, month, day = x['A'].split('-')
 	return f"{year}年{month}月{day}日"
 
 df['中文日期'] = df.apply(get_date, axis=1)

问题:怎样将“2020年5月1日”中的年、月、日三个中文字符去除?

方法一:链式replace
df['中文日期'].str.replace('年', '').str.replace('月', '').str.replace('日', '')

方法二:正则表达式替换
df['中文日期'].str.replace('[年月日]', '')

10.Pandas的axis参数

在这里插入图片描述

df = pd.DataFrame(
	np.arange(12).reshape(3, 4),
	columns=['A', 'B', 'C', 'D']
)

在这里插入图片描述
(1)单列drop,就是删除某一列

代表删除某列
df.drop('A', axis=1)

(2)单行drop,就是删除某一行

代表删除某行
df.drop(1, axis=0)

(3)按axis=0/index执行mean聚合操作

输出的不是每行的结果,而是每列的结果

df.mean(axis=0)

在这里插入图片描述
指定了哪个axis,就是这个axis要动起来,其他的axis保持不动
在这里插入图片描述
(4)按axis=1/icolumns执行mean聚合操作

输出的不是每行的结果,而是每列的结果

df.mean(axis=1)

在这里插入图片描述
在这里插入图片描述
(5)加深理解

def get_sum_value(x):
	return x['A'] + x['B'] + x['C'] + x['D']

df['sum_value'] = df.apply(get_sum_value, axis=1)

在这里插入图片描述

11.Pandas的索引index

11.1 使用index查询数据

在这里插入图片描述

drop=False,让索引列还保持在column
df.set_index('userId', inplace=True, drop=False)

在这里插入图片描述

使用index的查询方法
df.loc[500].head(5)

使用column的condition查询方法
df.loc[df['userId']==500].head()

11.2 使用index会提升查询性能

在这里插入图片描述
(1)完全随机的顺序查询

将数据随机打散
from sklearn.utils import shuffle
df_shuffle = shuffle(df)

df_shuffle.head()

在这里插入图片描述

索引是否是递增的
df_shuffle.index.is_monotonic_increasing

索引是否唯一
df_shuffle.index.is_unique

计时,查询id=500数据性能
%timeit df_shuffle.loc[500]

在这里插入图片描述
(2)将index排序后的查询

df_sorted = df_shuffle.sort_index()

%timeit df_shuffle.loc[500]

在这里插入图片描述
(3)index能自动对齐数据

s1 = pd.Series([1, 2, 3], index=list('abc'))
s2 = pd.Series([2, 3, 4], index=list('bcd'))

s1 + s2

在这里插入图片描述
(4)使用index可以有更多更强大的数据结构支持

在这里插入图片描述

12.Pandas实现DataFrame的Merge

在这里插入图片描述

12.1 电影数据集的join实例

在这里插入图片描述
(1)导入ratings表

import pandas as pd

df_ratings = pd.read_csv(
    "./datas/movielens-1m/ratings.dat", 
    sep="::",
    engine='python', 
    names="UserID::MovieID::Rating::Timestamp".split("::")
)

df_ratings.head()

在这里插入图片描述
(2)导入users表

df_users = pd.read_csv(
    "./datas/movielens-1m/users.dat", 
    sep="::",
    engine='python', 
    names="UserID::Gender::Age::Occupation::Zip-code".split("::")
)

df_users.head()

在这里插入图片描述
(3)导入movies表

df_movies = pd.read_csv(
    "./datas/movielens-1m/movies.dat", 
    sep="::",
    engine='python', 
    names="MovieID::Title::Genres".split("::")
)

df_movies.head()

在这里插入图片描述
(4)将ratings表和users表进行内连接

df_ratings_users = pd.merge(
   df_ratings, df_users, left_on="UserID", right_on="UserID", how="inner"
)

df_ratings_users.head()

在这里插入图片描述
(5)将ratings_users表和movies表进行内连接

df_ratings_users_movies = pd.merge(
    df_ratings_users, df_movies, left_on="MovieID", right_on="MovieID", how="inner"
)

df_ratings_users_movies.head(10)

在这里插入图片描述

12.2 理解merge时数量的对齐关系

在这里插入图片描述
(1)one-to-one 一对一关系的merge
在这里插入图片描述

left = pd.DataFrame({'sno': [11, 12, 13, 14],
                      'name': ['name_a', 'name_b', 'name_c', 'name_d']
                    })
right = pd.DataFrame({'sno': [11, 12, 13, 14],
                      'age': ['21', '22', '23', '24']
                    })

pd.merge(left, right, on='sno')

在这里插入图片描述
(2)one-to-many 一对多关系的merge
在这里插入图片描述

left = pd.DataFrame({'sno': [11, 12, 13, 14],
                      'name': ['name_a', 'name_b', 'name_c', 'name_d']
                    })
right = pd.DataFrame({'sno': [11, 11, 11, 12, 12, 13],
                       'grade': ['语文88', '数学90', '英语75','语文66', '数学55', '英语29']
                     })

数目以多的一边为准
pd.merge(left, right, on='sno')

在这里插入图片描述
(3)many-to-many 多对多关系的merge
在这里插入图片描述

left = pd.DataFrame({'sno': [11, 11, 12, 12,12],
                      '爱好': ['篮球', '羽毛球', '乒乓球', '篮球', "足球"]
                    })
right = pd.DataFrame({'sno': [11, 11, 11, 12, 12, 13],
                       'grade': ['语文88', '数学90', '英语75','语文66', '数学55', '英语29']
                     })

pd.merge(left, right, on='sno')

在这里插入图片描述

12.3 理解left join、right join、inner join、outer join的区别

在这里插入图片描述

left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                      'A': ['A0', 'A1', 'A2', 'A3'],
                      'B': ['B0', 'B1', 'B2', 'B3']})

right = pd.DataFrame({'key': ['K0', 'K1', 'K4', 'K5'],
                      'C': ['C0', 'C1', 'C4', 'C5'],
                      'D': ['D0', 'D1', 'D4', 'D5']})

在这里插入图片描述
在这里插入图片描述
(1)inner join,默认

左右两边的key都有,才会出现在结果里

pd.merge(left, right, how='inner')

在这里插入图片描述
(2)left join

左边的都会出现在结果里,右边的如果无法匹配则为Null

pd.merge(left, right, how='left')

在这里插入图片描述
(3)right join

右边的都会出现在结果里,左边的如果无法匹配则为Null

pd.merge(left, right, how='right')

在这里插入图片描述
(4)outer join

左边、右边的都会出现在结果里,如果无法匹配则为Null

pd.merge(left, right, how='outer')

在这里插入图片描述

12.4 重名字段

left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                      'A': ['A0', 'A1', 'A2', 'A3'],
                      'B': ['B0', 'B1', 'B2', 'B3']})

right = pd.DataFrame({'key': ['K0', 'K1', 'K4', 'K5'],
                      'A': ['A10', 'A11', 'A12', 'A13'],
                      'D': ['D0', 'D1', 'D4', 'D5']})

在这里插入图片描述

pd.merge(left, right, on='key')

在这里插入图片描述

pd.merge(left, right, on='key', suffixes=('_left', '_right'))

在这里插入图片描述

13.Pandas实现数据的合并concat

在这里插入图片描述

13.1 使用pandas.concat合并数据

(1)导入包,忽略警告

import pandas as pd

import warnings
warnings.filterwarnings('ignore')

df1

df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3'],
                    'E': ['E0', 'E1', 'E2', 'E3']
                   })

在这里插入图片描述
df2

df2 = pd.DataFrame({ 'A': ['A4', 'A5', 'A6', 'A7'],
                     'B': ['B4', 'B5', 'B6', 'B7'],
                     'C': ['C4', 'C5', 'C6', 'C7'],
                     'D': ['D4', 'D5', 'D6', 'D7'],
                     'F': ['F4', 'F5', 'F6', 'F7']
                   })

在这里插入图片描述
(2)默认的concat,参数为axis=0、join=outer、ignore_index=False

pd.concat([df1,df2])

在这里插入图片描述
(3)使用ignore_index=True可以忽略原来的索引

pd.concat([df1,df2], ignore_index=True)

在这里插入图片描述
(4)使用join=inner过滤不匹配的列

pd.concat([df1,df2], ignore_index=True, join="inner")

在这里插入图片描述
(5)使用axis=1相当于添加新列

添加一列Series

s1 = pd.Series(list(range(4)), name="F")
pd.concat([df1,s1], axis=1)

在这里插入图片描述
添加多列Series

s2 = df1.apply(lambda x:x["A"]+"_GG", axis=1)

s2.name="G"

pd.concat([df1,s1,s2], axis=1)

在这里插入图片描述
在这里插入图片描述
列表可以只有Series

pd.concat([s1,s2], axis=1)

列表是可以混合顺序的

pd.concat([s1,df1,s2], axis=1)

在这里插入图片描述

13.2 使用DataFrame.append按行合并数据

df1 = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB'))

在这里插入图片描述

df2 = pd.DataFrame([[5, 6], [7, 8]], columns=list('AB'))

在这里插入图片描述
(1)给一个DataFrame添加另一个DataFrame

df1.append(df2)

在这里插入图片描述
(2)忽略原来的索引ingore_index=True

df1.append(df2, ignore_index=True)

在这里插入图片描述
(3)可以一行行的给DataFrame添加数据

一个空的df
df = pd.DataFrame(columns=['A'])
for i in range(5):
    # 注意这里每次都在复制
    df = df.append({'A': i}, ignore_index=True)
# 第一个入参是一个列表,避免了多次复制
pd.concat(
    [pd.DataFrame([i], columns=['A']) for i in range(5)],
    ignore_index=True
)

在这里插入图片描述

14.Pandas批量拆分与合并Excel

14.1 读取源Excel到Pandas

work_dir="./course_datas/c15_excel_split_merge"
splits_dir=f"{work_dir}/splits"

import os
if not os.path.exists(splits_dir):
    os.mkdir(splits_dir)
import pandas as pd

df_source = pd.read_excel(f"{work_dir}/crazyant_blog_articles_source.xlsx")
df_source.head()

在这里插入图片描述

14.2 将一个大Excel等份拆成多个Excel

  • 使用df.iloc方法,将一个大的DataFrame,拆分成多个小DataFrame
  • 使用DataFrame.to_excel保存每个小Excel

(1)计算拆分后的每个Excel的行数

这个大excel,会拆分给这几个人
user_names = ["xiao_shuai", "xiao_wang", "xiao_ming", "xiao_lei", "xiao_bo", "xiao_hong"]

总行数
total_row_count = df_source.shape[0]

每个人的任务数目
split_size = total_row_count // len(user_names)
if total_row_count % len(user_names) != 0:
    split_size += 1

(2)拆分成多个DataFrame

df_subs = []
for idx, user_name in enumerate(user_names):
    iloc的开始索引
    begin = idx*split_size
    
    iloc的结束索引
    end = begin+split_size
    
    实现df按照iloc拆分
    df_sub = df_source.iloc[begin:end]
    
    将每个子df存入列表
    df_subs.append((idx, user_name, df_sub))

(3)将每个DataFrame存入Excel

for idx, user_name, df_sub in df_subs:
    file_name = f"{splits_dir}/crazyant_blog_articles_{idx}_{user_name}.xlsx"
    df_sub.to_excel(file_name, index=False)

14.3 合并多个小Excel到一个大Excel

  • 遍历文件夹,得到要合并的Excel文件列表
  • 分别读取到DataFrame,给每个df添加一列用于标记来源
  • 使用pd.concat进行df批量合并
  • 将合并后的DataFrame输出到Excel

(1)遍历文件夹,得到要合并的Excel名称列表

import os
excel_names = []
for excel_name in os.listdir(splits_dir):
    excel_names.append(excel_name)
excel_names

在这里插入图片描述
(2)分别读取到DataFrame

df_list = []

for excel_name in excel_names:
    读取每个excel到df
    excel_path = f"{splits_dir}/{excel_name}"
    df_split = pd.read_excel(excel_path)
    
    得到username
    username = excel_name.replace("crazyant_blog_articles_", "").replace(".xlsx", "")[2:]
    print(excel_name, username)
    
    给每个df添加1列,即用户名字
    df_split["username"] = username
    
    df_list.append(df_split)

在这里插入图片描述
(3)使用pd.concat进行合并

df_merged = pd.concat(df_list)

df_merged["username"].value_counts()

在这里插入图片描述
(4)将合并后的DataFrame输出到Excel

df_merged.to_excel(f"{work_dir}/crazyant_blog_articles_merged.xlsx", index=False)

15.Pandas的分组聚合groupby

类似SQL:
select city,max(temperature) from city_weather group by city;

groupby:先对数据分组,然后在每个分组上应用聚合函数、转换函数

import pandas as pd
import numpy as np

加上这一句,能在jupyter notebook展示matplot图表
%matplotlib inline

df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
                   'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
                   'C': np.random.randn(8),
                   'D': np.random.randn(8)})

在这里插入图片描述

15.1 使用聚合函数做数据统计

(1)单个列groupby,查询所有数据列的统计

df.groupby('A').sum()

在这里插入图片描述
(2)多个列groupby,查询所有数据列的统计

df.groupby(['A','B']).mean()

在这里插入图片描述

df.groupby(['A','B'], as_index=False).mean()

在这里插入图片描述
(3)同时查看多种数据统计

df.groupby('A').agg([np.sum, np.mean, np.std])

在这里插入图片描述
(4)查看单列的结果数据统计

方法一:预过滤,性能更好
df.groupby('A')['C'].agg([np.sum, np.mean, np.std])

在这里插入图片描述

方法二:
df.groupby('A').agg([np.sum, np.mean, np.std])['C']

在这里插入图片描述
(5)不同列使用不同的聚合函数

df.groupby('A').agg({"C":np.sum, "D":np.mean})

在这里插入图片描述

15.2 遍历groupby的结果理解执行流程

for循环可以直接遍历每个group

(1)遍历单个列聚合的分组

g = df.groupby('A')

for name,group in g:
    print(name)
    print(group)
    print()

在这里插入图片描述
可以获得单个分组的数据

g.get_group('bar')

在这里插入图片描述
(2)遍历多个列聚合的分组

g = df.groupby(['A', 'B'])


for name,group in g:
    print(name)
    print(group)
    print()

在这里插入图片描述

g.get_group(('foo', 'one'))

在这里插入图片描述
可以直接查询group后的某几列,生成Series或者子DataFrame

g['C']

for name, group in g['C']:
    print(name)
    print(group)
    print(type(group))
    print()

在这里插入图片描述

15.3 实例分组探究天气数据

fpath = "./datas/beijing_tianqi/beijing_tianqi_2018.csv"
df = pd.read_csv(fpath)
# 替换掉温度的后缀℃
df.loc[:, "bWendu"] = df["bWendu"].str.replace("℃", "").astype('int32')
df.loc[:, "yWendu"] = df["yWendu"].str.replace("℃", "").astype('int32')
df.head()

在这里插入图片描述

新增一列为月份
df['month'] = df['ymd'].str[:7]
df.head()

在这里插入图片描述
(1)查看每个月的最高温度

data = df.groupby('month')['bWendu'].max()

在这里插入图片描述

data.plot()

在这里插入图片描述
(2)查看每个月的最高温度、最低温度、平均空气质量指数

group_data = df.groupby('month').agg({"bWendu":np.max, "yWendu":np.min, "aqi":np.mean})

在这里插入图片描述

group_data.plot()

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值