Bootstrap

【python】Pandas 数据分析之数据拼接与缺失值处理\建议在Jupyter Notebook 中运行

建议在Jupyter Notebook 中运行
jupyter notebook环境搭建

import numpy as np
import pandas as pd

import sqlite3

import  os
os.chdir(r'D:\hm\homework\pywork\workProject\numpyProject')

1.演示数据拼接

1.1 加载数据

df1 = pd.read_csv('./data/concat_1.csv')
df2 = pd.read_csv('./data/concat_2.csv')
df3 = pd.read_csv('./data/concat_3.csv')
print(df1,df2,df3)

1.2 df对象和 df对象拼接

# concat()函数 既能实现行拼接(默认) 也能实现列拼接 行拼接参考 : 列名 列拼接参考 :索引列(行索引)

# 1.演示行列拼接

pd.concat([df1,df2,df3]) # 行拼接默认



pd.concat([df1,df2,df3],axis='rows') # 行拼接

pd.concat([df1,df2,df3],axis=0) # 0 是 rows 行 效果同上 1是 columns 列

pd.concat([df1,df2,df3],axis=1) # 1 columns 列

# 演示行列拼接时重置 索引和列名

# 无论是 行 还是 列 拼接时 只要忽略索引了 都会用 0~n来填充

pd.concat([df1,df2,df3],axis = 'rows', ignore_index = True) # 行拼接

pd.concat([df1,df2,df3],axis = 'columns', ignore_index = True) # 列拼接

# 行拼接时,参考列名

df4 = pd.DataFrame(['n1','n2','n3'],columns=['A'])
df4
pd.concat([df1,df4],axis= 0) # 未匹配用NAN填充

1.3 df对象和Series对象 拼接

#1. 创建series 对象
s1 = pd.Series(['n1','n2','n3'])
s1



# 2. 使用 concat 拼接df 和 series 对象

pd.concat([df1,s1]) #行拼接

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

df1.append(df2)

pd.concat([df1, df2])
## 1.4 给df对象新增 1列

# 方式1 df对象[列名] = 列表 要求: 列表的长度 要和 df的行数 一致

df1['new_col1'] = [10,20,30,40]
df1

# 方式2 df对象[列名] = series 对象 series对象 值的个数无要求

df1['new_col2'] = pd.Series([1,2,3,4,5])
df1['new_col3'] = pd.Series([1,2,3])
df1['new_col4'] = pd.Series([1,2,3,4])
df1

2.演示 merge() 函数

2.1准备动作

# 1.加载数据 获取 df对象

conn = sqlite3.connect('data/chinook.db')

# 2.从文件中 读取歌曲表的信息

# 参一 sql语句 参二 连接对象

tracks_df = pd.read_sql_query('select * from tracks;',conn)
tracks_df.head()

# 3.从上述的文件中读取歌曲分类表信息

genres_df = pd.read_sql_query('select * from genres;',conn)
genres_df.head()

2.2 merge()合并数据 一对一关系

#1. 查看歌曲风格表的信息
genres_df.head()

# 2. 查看歌曲表的信息,并从中找到 不同的音乐风格的数据

tracks_subset_df = tracks_df.loc[[0,62,76,98,110,193,204,281]]
tracks_subset_df[['TrackId','GenreId','Milliseconds']]

# 3. 合并上述两个表 以 风格为标准合并

# 场景1 内连接

# 参1 : 要被合并的df对象 

# 参2 : on表述两个df合并的 关联字段 如果一样直接写 on 如果不一样 则要写

# left_on = '左表字段名' right_on = '右表字段名'

# 参3 : how表示合并方式 内连接 inner 左连接 left 右链接 right 全(满)连接 outer 默认inner

genres_df.merge(tracks_subset_df[['TrackId','GenreId','Milliseconds']], on ='GenreId',how='inner')

# 左外连接

genres_df.merge(tracks_subset_df[['TrackId','GenreId','Milliseconds']], on ='GenreId',how='left')

# 右外连接

genres_df.merge(tracks_subset_df[['TrackId','GenreId','Milliseconds']], on ='GenreId',how='right')

#满外连接
genres_df.merge(tracks_subset_df[['TrackId','GenreId','Milliseconds']], on ='GenreId',how='outer')

# 如果 关联的多个df有重名的列 则会默认加上 _x _y 这样的 后缀 来源于 suffixes字段 可以通过 suffixes 修改

genres_df.merge(tracks_subset_df[['TrackId','Name','GenreId','Milliseconds']], on ='GenreId')
genres_df.merge(tracks_subset_df[['TrackId','Name','GenreId','Milliseconds']], on ='GenreId',suffixes=('_left','_right'))

2.3 merge() 合并数据 一对多的关系

# 合并 genres 和 tracks 表 

genres_df.merge(tracks_subset_df[['TrackId','Name','GenreId','Milliseconds']], on ='GenreId')

# 计算每种类型音乐的平均市场

# 1. 合并genres(风格表) 和 tracks(歌曲表), 交集

genres_track = genres_df.merge(tracks_df[['TrackId','GenreId','Milliseconds']],on='GenreId')
genres_track

# 2.根据风格id分组 计算时长的平局值

genre_time = genres_track.groupby('GenreId').Milliseconds.mean()
genre_time

pd.to_timedelta(genre_time,unit='ms').dt.floor('s').sort_values()

# 总结: merge() 1.默认是inner 2.关联字段不一致 用 right_on  和 right_on  3. 两个字段有重名 可以通过 suffixes 解决 默认是 _x _y

# 3.演示 join() 合并

# 1. 加载数据 获取df对象

stock_2016 = pd.read_csv('./data/stocks_2016.csv')
stock_2017 = pd.read_csv('./data/stocks_2017.csv')
stock_2018 = pd.read_csv('./data/stocks_2018.csv')
stock_2016
stock_2017
stock_2018

# 2. 默认情况下 join 会参考 df 索引列进行合并连接

stock_2016.join(stock_2017,lsuffix='_2016',rsuffix='_2017') # 默认左外连接

# 3. 设置 两个df对象的Symbol 列为索引列 再次关联

#设置索引列并关联 
stock_2016.set_index('Symbol').join(stock_2017.set_index('Symbol'),lsuffix='_2016',rsuffix='_2017') # 左外连接
stock_2016.set_index('Symbol').join(stock_2017.set_index('Symbol'),lsuffix='_2016',rsuffix='_2017',how = 'right') # 右外连接
stock_2016.set_index('Symbol').join(stock_2017.set_index('Symbol'),lsuffix='_2016',rsuffix='_2017',how = 'outer') # 满外连接 全连接
stock_2016.set_index('Symbol').join(stock_2017.set_index('Symbol'),lsuffix='_2016',rsuffix='_2017',how = 'inner') # 内连接 

# 4. 设置stock_2016 的索引 为:symbol 和 stock_2018 做关联

stock_2018.join(stock_2016.set_index('Symbol'),lsuffix='_2016',rsuffix='_2018',on = 'Symbol',how = 'right') 

# on 参数设定的是函数外 df对象的普通列

# 总结 join 

# 1.默认是左外连接  

# 2.如果有重名字段 需要手动设置后缀名 lsuffix rsuffix

# 3. 可以通过 on 来实现 索引列 和 普通列 做关联
mport numpy as np
import pandas as pd

import sqlite3
import missingno as msno
import  os
os.chdir(r'D:\hm\homework\pywork\workProject\numpyProject')

3.演示缺失值查看和比较

# 在 pandas 中 缺失值来源于 numpy 中 的 NAN nan NaN 他们都表示空

# 1.空值比较

print(np.NAN == True)
print(np.NAN == False)
print(np.NAN == '')
print(np.NAN == 0)

# 2.空和空比较 也都是 False

print(np.NAN == np.nan)
print(np.NAN == np.NaN)
print(np.NAN == np.NAN)

# 3.判断是否为空

print(pd.isnull(np.NAN)) # True
print(pd.isnull('')) # False

print(pd.notnull(np.NAN)) # False
print(pd.notnull('')) # True

4.泰坦尼克号数据集 演示:删除 填充数据集

4.1 加载数据 查看缺失信息

# 1.读取数据 获取df对象

train = pd.read_csv('./data/titanic_train.csv')
train.head()

# 2.查看数据常用的统计值

train.shape

train.info()

train.describe() 

# 3. 报表的形式 查看缺失值

msno.bar(train) #柱状图

msno.heatmap(train) # 查看缺失值之间的关联性

4.2 删除缺失值

# 1. 查看df 对象 

train.isnull().sum() # 查看各列空值情况

# 2. 删除空值

train.dropna() # 默认按行删除 
train.dropna(axis = 'rows') # 效果同上 按行删除 
train.dropna(axis = 0) # 效果同上 按行删除 
train.dropna(axis = 'columns') # 按列删除
train.dropna(axis = 1) # 效果同上 按列删除 

# subset 参数 : 参考的列 即: 该列值为空 才会删除行对应的列

# how 参数 : any 只要有空值 就会 删除` all 都为空值才会删除 

train.dropna(subset= ['Age','Embarked'],how = 'all') 
train.dropna(subset= ['Age','Embarked'],how = 'any')  

# 查看删除后的数据

train.dropna(subset= ['Age','Embarked'],how = 'any').isnull().sum()

train.dropna(subset= ['Cabin','Age']) 
;