数据分析
什么是数据分析
用适当的统计分析方法对收集的大量数据进行分析,提取有用信息,对数据加以分析和概括的过程。
数据分析师需要具备的能力
- 数理知识
- 数据获取、加工能力
- 行业知识
数据分析步骤
基本步骤:明确目的思路 --> 数据收集 --> 数据处理 --> 数据分析 --> 数据展现
数据加载
我们需要将收集的数据加载到内存中,进行下一步的分析。pandas提供丰富读取数据的函数,读取位于不同数据源中的数据,常用函数为:
- read_csv 读取csv文件 读取 分隔符为 ' , ' 的文件
- read_table 读取 分隔符 '\t'的 文件
- read_sql 从数据库中读取文件
常用参数
- sep/delimiter
- header
- names
- index_col
- usecols
In [2]:
import numpy as np
import pandas as pd
# read_csv方法读取csv文件,返回DataFrame对象,默认将第一行作为DataFrame的列标签
# df = pd.read_csv('data.csv')
# display(df)
# 设置header=None,csv文件第一行就不会作为我们的列标签
# df = pd.read_csv('data.csv',header=None)
# display(df)
# sep/delimiter,设置读取分隔符
# df = pd.read_csv('data.csv',header=None,sep='-')
# df = pd.read_csv('data.csv',header=None,delimiter='-')
# display(df)
# names设置列索引
# df = pd.read_csv('data.csv',header=None,names=['姓名','年龄','身高','体重'])
# display(df)
# index_col设置行索引
# df = pd.read_csv('data.csv',header=None,index_col=0)
# display(df)
# usecols设置从文件中读取我们所需要的列
# df = pd.read_csv('data.csv',header=None,usecols=[1,2])
# display(df)
# 如果数据中某列充当行索引,此列的列标签也必须在usecols中设置
df = pd.read_csv('data.csv',header=None,index_col=0,usecols=[0,1,2])
display(df)
| | 1 | 2 | | ---- | ---- | ---- | | 0 | | | | 1 | 2 | 3 | | a | b | c | | 11 | 12 | a |
In [454]:
# web中获取数据
# read_table和read_csv都可以获取网络上数据,以及本地文本数据,区别仅仅在于数据的分隔符
# read_table 分隔符 '\t' read_csv 分隔符 ','
# df = pd.read_csv('http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt')
# display(df.head())
# 从数据库中获取数据
# import pymysql
# # 得到数据库连接
# conn = pymysql.connect('localhost','root','root','sxt001')
# # 将sql,conn传入read_sql,读取数据库中数据
# df = pd.read_sql('select * from tb_user',conn)
# display(df.head())
# 从excel中读取数据
# df = pd.read_excel('data/Eueo2012_excel.xlsx',sheetname='Eueo2011')
# display(df.head())
# 从json中获取数据
df = pd.read_json('data/data.json')
display(df.head())
| | editor | group | name | value | | ---- | --------- | ----------- | -------- | ------------ | | 0 | text | ID Settings | Name | Bill Smith | | 1 | text | ID Settings | Address | | | 2 | numberbox | ID Settings | Age | 40 | | 3 | datebox | ID Settings | Birthday | 01/02/2012 | | 4 | text | ID Settings | SSN | 123-456-7890 |
写入文件
DataFrame与Sereis的to_csv方法能将数据写入到文件中
常用参数
- index:是否写入行索引,默认为True
- index_lable:索引字段名称
- header:是否写入列索引,默认为True
- na_rep:空值表示
- columns:写入的字段,默认为全部写入
- sep:分隔符
In [18]:
df = pd.DataFrame(np.arange(1,10).reshape(3,3))
display(df)
# to_csv将DataFrame对象写入到文件中
df.to_csv('data.csv')
# df=pd.read_csv('data.csv')
# display(df)
# index,默认为True。使用index设置是否写入行索引,True写入,False不写入
# df.to_csv('data.csv',index=False)
# index_label:设置行索引对象的name信息
# df.to_csv('data.csv',index=True,index_label='index_name')
# header设置DataFrame对象列索引写入,True写入(默认),False不写入
# df.to_csv('data.csv',header=False)
# df[0]=np.nan
# display(df)
# # 空值默认写入到文件中不显示,na_rep指定文件中空值的显示效果
# df.to_csv('data.csv',header=False,na_rep='空')
# columns设置DataFrame对象哪些列写入到文件,默认写入所有的列
# df.to_csv('data.csv',header=False,columns=[1,2])
# sep,默认写入文件以逗号为分隔符,sep可以自定义分隔符
df.to_csv('data.csv',header=False,sep='-')
| | 0 | 1 | 2 | | ---- | ---- | ---- | ---- | | 0 | 1 | 2 | 3 | | 1 | 4 | 5 | 6 | | 2 | 7 | 8 | 9 |
数据清洗
收集到的数据,无法保证数据一定准确、有效的,需要对其进行清洗。数据清洗包含以下几个方面。
- 处理缺失值
- 处理异常值
- 处理重复值
缺失值处理
发现缺失值
pandas中,将float类型的nan与None视为缺失值,如下方法可检测缺失值:
- info 对整体数据进行查看,显示DataFrame对象每列相关信息
- isnull
- notnull
isnull和any或者all可以结合使用
丢弃缺失值
对于缺失值,可通过dropna方法进行丢弃处理 参数
- how:指定dropna丢弃缺失值行为,默认为any
- axis:指定丢弃行或者丢弃列,默认丢弃行
- thresh:当非空数值达到该值时,保留数据,否则删除
- inplace:指定是否就地修改,默认为Flase
填充缺失值
对于缺失值,可通过fillna方法进行填充 参数
- value:填充所用的值,可以是一个字典,这样为DataFrame不同列指定不同填充值
- method:指定上一个有效值填充(pad/ffill),还是下一个有效值填充(backfill/bfill)
- limit:如果指定method,表示最大连续NaN的填充数量,如果没有指定method,表示最大的NaN填充数量
- inplace:指定是否就地修改,默认为Flase
In [ ]:
# 读取泰坦尼克号数据-titanic_train.csv
df = pd.read_csv('data/titanic_train.csv',header=None)
display(df)
# 检查缺失值,使用info对整体数据进行查看,显示DataFrame对象每列相关信息
# display(df.info())
# isnull发现缺失值
# display(df.isnull())
# display(df[10].isnull())
# any返回True,说明这一列存在至少一个缺失值
# display(df[10].isnull().any())
# # all返回True,说明这一列都是空值
# display(df[10].isnull().all())
# 默认情况下,how=any,只要存在缺失值,直接丢弃行
# display(df.dropna())
# how=all,全为缺失值,才丢弃
# display(df.dropna(how='all'))
# 存在空值,默认删除行,设置axis=1,丢弃列
# display(df.dropna(axis=1))
# how设置any和all都不合适,any条件太宽松,all太严格,自定义非空数据少于某个阈值才删除,thresh
# thresh=11,当非空的数据个数少于11个,删除数据
display(df.dropna(thresh=11))
In [ ]:
# 读取泰坦尼克号数据-titanic_train.csv
df = pd.read_csv('data/titanic_train.csv',header=None)
# display(df)
# 使用固定值(均值或中位数)填充所有列缺失值
# display(df.fillna(1000))
# 提供字典,为不同列填充不同值。key指定填充对应的索引,value指定填充值
# display(df.fillna({5:500,10:1000}))
# method,指定前后的有效数据填充
# display(df.fillna(method='ffill')) # 指定上一个有效值填充
# display(df.fillna(method='bfill')) # 指定下一个有效值填充
# limit,单独使用,表示每列总共填充缺失值个数
# display(df.fillna(value=1000,limit=1))
# limit参数结合使用,表示最多连续填充个数
display(df.fillna(method='bfill',limit=2))
无效值处理
检测无效值
通过 DataFrame 的 describe 方法查看数据统计,不同类型统计信息不同。基于统计信息,再结合业务来检查无效值
In [110]:
# df = pd.read_csv('data.csv',header=None)
# display(df)
# display(df.describe())
df = pd.read_csv('data/titanic_train.csv')
# display(df)
# display(df.describe())
display(df[['Name','Sex','Ticket']].describe())
| | Name | Sex | Ticket | | ------ | ------------------------ | ---- | ------ | | count | 891 | 891 | 891 | | unique | 891 | 2 | 681 | | top | Mannion, Miss. Margareth | male | 1601 | | freq | 1 | 577 | 7 |
重复值处理
对于数据中的重复数据,通常将重复数据删除
发现重复值
通过duplicated方法发现重复值。该方法返回Series类型对象,值为布尔类型,表示是否与上一行重复 参数说明
- subset:指定依据哪些列判定是否重复,默认为所有列
- keep:指定数据标记为重复(True)的规则。默认为first
删除重复值
通过drop_duplicates删除重复值 参数说明
- subset:指定依据哪些列判断是否重复,默认为所有列
- keep:指定记录删除(或保留)的规则,默认为first
- inplace:指定会否就地删除,默认为False
In [119]:
df = pd.read_csv('data/duplicate.csv',header=None)
display(df)
# duplicate检查重复值,返回的Sereis对象,True表示重复,False表示不重复
# display(df.duplicated())
# 结合any,判断整个数据是否有重复的数据
# display(df.duplicated().any())
# keep参数:重复N条数据,first-后面的数据标记为True,last--前面的数据标记为True;False,所有的数据都标记为True
# display(df.duplicated(keep='last'))
# display(df.duplicated(keep=False))
# subset 指定重复规则,默认所有列重复才重复
# display(df.duplicated(subset=[0,1]))
# 删除重复数据
df.drop_duplicates(keep='first')
| | 0 | 1 | 2 | 3 | | ---- | ---- | ---- | ---- | ---- | | 0 | 1 | 2 | 3 | 4 | | 1 | 2 | 2 | 2 | 3 | | 2 | 1 | 2 | 1 | 1 | | 3 | 1 | 2 | 1 | 1 | | 4 | 2 | 2 | 2 | 3 | | 5 | 3 | 2 | 1 | 2 | | 6 | 2 | 3 | 3 | 5 |
Out[119]:
| | 0 | 1 | 2 | 3 | | ---- | ---- | ---- | ---- | ---- | | 0 | 1 | 2 | 3 | 4 | | 1 | 2 | 2 | 2 | 3 | | 2 | 1 | 2 | 1 | 1 | | 5 | 3 | 2 | 1 | 2 | | 6 | 2 | 3 | 3 | 5 |
数据过滤
使用布尔数组或者索引数组来过滤数据;另外也可以使用DataFrame的query方法来进行数据过滤。 如果query方法中使用外面定义的变量需要在变量前加上@
In [143]:
df = pd.read_csv('data/titanic_train.csv')
# display(df)
# 给定一个条件,根据条件生成布尔数组
# display(df['Survived']==1)
# 将得到的布尔数组传回给DataFrame对象进行过滤
# display(df[df['Survived']==1])
# 注意点,返回的是一个新的DataFrame对象
# df = df[df['Survived']==1]
# display(df)
# 多个条件
# bArray=(df['Survived']==1)&(df['Pclass']==1)
# display(df[bArray])
# 使用query方法进行过滤
# 1个条件
# display(df.query('Survived==1'))
# 多个条件
# display(df.query('(Survived==1)&(Pclass==1)'))
# 条件值为变量
val = 1
display(df.query('Survived==@val'))
数据转换
应用与映射
Sereis和DataFrame都有对元素的映射转换操作,DataFrame作为二维数据还具有行和列对应转换操作。 对于Sereis,可以调用apply或者map方法。对于DataFrame,可以调用apply或applymap方法。
- apply:传入函数实现映射转化。函数参数,Series传递元素,DataFrame传递行和列对象
- map:对当前Series的值进行映射转换。参数可以是Series,字典或者函数
- applymap:传入函数实现元素的映射转换
替换
Sereis和DataFrame可以通过replace方法实现元素值的替换
- to_replace:被替换值,支持单一值、列表、字典和正则表达式
- regex:是否使用正则表达式,默认为False
字符串向量化运算
Series含有str属性,通过str能对字符串进行向量级运算,从而对数据进行转换
In [ ]:
# apply可以对Sereis,DataFrame进行应用和映射的数据转换
# 向apply方法传递函数,需要定义一个参数。对于Sereis,依次传递每一个元素给参数。对于DataFrame,依次传递每一行或者每一列(axis参数)
# 函数返回值表示参数处理后的结果
# 对Series
# apply方法,依次将s的元素传递给handle方法参数,handle方法对元素进行处理,将处理的结果返回
def handle(x):
return x**2,x**3
# s = pd.Series([1,2,3,4])
# s = s.apply(handle)
# display(s)
# 函数特别简单,只有一行语句,lambda表达式,给apply传入匿名方法
# s = pd.Series([1,2,3,4])
# s = s.apply(lambda x:x**3)
# display(s)
# 返回多个值
s = pd.Series([1,2,3,4])
s = s.apply(handle)
display(s)
In [ ]:
# apply处理DataFrame
# 每行的female --》女,male-->男
def handle(row):
if row.loc['Sex']=='female':
row.loc['Sex']='女'
else:
row.loc['Sex']='男'
return row
df = pd.read_csv('data/titanic_train.csv')
display(df.head())
# axis和之前一直谈到的有区别,axis=0列的数据,axis=1 行的数据
df = df.apply(handle,axis=1)
display(df.head())
In [ ]:
# map函数适用于Series对象
# 传入函数,和apply方法没有区别
# s = pd.Series([1,2,3,4])
# # s = s.map(lambda x:x**2)
# s = s.apply(lambda x:x**2)
# display(s)
# 传入Series
# s = pd.Series([1,2,3,4])
# map_series = pd.Series([11,12,13,14],index=[1,2,3,4])
# display(s,map_series)
# # 取s中一个值,和map_series索引进行匹配,匹配上,找到对应map_series中值映射给s
# display(s.map(map_series))
# 传入字典
s = pd.Series([1,2,3,4])
map_dict={1:11,2:12,3:13,4:14}
# 取s中一个值,和map_dict的key值进行匹配,匹配上,找到key对应value值映射给s
display(s.map(map_dict))
In [ ]:
# applymap对DataFrame的元素转换映射操作
# 参数作为函数,DataFrame的每一个元素都会调用一次该函数,将元素传递给该函数。处理后通过函数返回值返回映射结果
df = pd.read_csv('data/titanic_train.csv')
# display(df.head(),df.info())
display(df[['Age','Fare']])
df = df[['Age','Fare']].applymap(lambda x:x+10000)
display(df)
# df = df.applymap(lambda x:x+10000)
# display(df.head())
In [318]:
# replace 元素替换
df = pd.read_csv('data/bikes.csv')
# display(df.head(),df.info())
# replace单一值的替换 对DataFrame
# df = df.replace('4/16/2010','2010-4-16')
# display(df.head())
# # replace单一值的替换 对Series
# s = df['THEFT_DATE'].replace('4/16/2010','2010-4-16')
# display(s.head())
# replace支持列表 将列表元素替换value指定的值
# s = df['THEFT_DATE'].replace(['4/16/2010','4/24/2010'],'2010-4-16')
# display(s.head())
# replace支持列表多个值,每个替换为不同的值。列表执行对应位置替换
# s = df['THEFT_DATE'].replace(['4/16/2010','4/24/2010'],['2010-4-16','2010-4-24'])
# display(s.head())
# replace支持字典方式将多个值替换为不同的值,key指定要替换的值,value指定要替换什么值
# s = df['THEFT_DATE'].replace({'4/16/2010':'2010-4-16','4/24/2010':'2010-4-24'})
# display(s.head())
# 支持正则表达式
s = df['THEFT_DATE'].replace('4/16/[0-9]{4}','2010',regex=True)
display(s.head())
0 2010
1 4/24/2010
2 6/6/2010
3 7/8/2010
4 7/11/2010
Name: THEFT_DATE, dtype: object
In [ ]:
def m(item):
if item=='4/16/2010':
return '2010-4-16'
return item
# replace同样可以使用map或者applymap来实现
df = pd.read_csv('data/bikes.csv')
# s = df['THEFT_DATE'].replace('4/16/2010','2010-4-16')
# display(s.head())
s = df['THEFT_DATE'].map(m)
display(s.head())
In [ ]:
# Series 的str属性,支持向量化操作,实现数据转换
# s= pd.Series([1,2,3])
# display(s,s.dtype)
# display(s.str) # 错误,使用Sereis的str属性时,需要Series元素值是str(字符串)类型
# s= pd.Series(['a','b','c'])
# # display(s,s.dtype)
# # pandas.core.strings.StringMethods提供了很多方法(和python中str类型提供方法类似的),进行字符串向量化操作
# display(s.str)
# display(s.str.upper())
# display(s.str.contains('b'))
# 对数据做过滤
# df = pd.read_csv('data/earthquake_week.csv')
# # display(df.head())
# barray = df['place'].str.endswith('CA')
# # display(barray)
# df = df[barray]
# display(df)
# split方法对数据进行拆分
df = pd.read_csv('data/earthquake_week.csv')
display(df.head())
# expand=False,用一个列表存放拆分后的数据,expand=True,拆分为多列
# display(df['place'].str.split(',',expand=True))
数据合并
concat
通过pandas的concat方法,对DataFrame或者Series类型的进行连接操作。连接时,根据索引对齐。
- axis:指定连接轴,默认为0
- join:指定连接方式,默认为外连接。参数值outer:并集,inner:交集
- keys:用来区分不同的数据组
- join_axes:指定连接结果集中保留的索引
- ignore_index:忽略原来连接索引,创建新的整数序列索引,默认为False
append
Series或DataFrame的append方法可以对行进行连接操作
merge
通过pandas或者DataFrame的merge方法,可以进行两个DataFrame的连接,这种连接类似于SQL中对两张表进行join连接
- how:指定连接方式,可以是inner,outer,left,right,默认为inner
- on 指定连接使用的列(该列必须同时出现在两个DataFrame中),默认使用使用两个DataFrame所有同名列连接
- left_on/right_on:指定左右DataFrame连接所使用的列
- left_index/right_index:是否将左边(右边)DataFrame的索引作为连接列,默认为False
- suffixes:当两个DataFrame列名相同时,指定每个列名的后缀(用来区分),默认为x与y
join
与merge方法类似,但是默认使用行索引进行连接。
- how:指定连接方式。可以使用Inner、outer、left、right,默认是left
- on:设置当前DataFrame使用哪个列与参数DataFrame对象的行索引进行连接
- isuffix/rsuffix:当两个DataFrame列名相同时,指定每个列名的后缀(用来区分),如果不指定,列名相同会产生错误
In [364]:
# df1 = pd.DataFrame(np.arange(1,10).reshape(3,3))
# df2 = pd.DataFrame(np.arange(10,19).reshape(3,3),columns=[1,2,3])
# display(df1,df2)
# # 进行concat连接时候,根据索引(默认索引)对齐合并,如果不对齐,产生空值
# display(pd.concat((df1,df2)))
# axis指定数据连接方向,axis=0 竖直,列索引对齐;axis=1水平方向,行索引对齐
# df1 = pd.DataFrame(np.arange(1,10).reshape(3,3))
# df2 = pd.DataFrame(np.arange(10,19).reshape(3,3),index=[1,2,3])
# display(df1,df2)
# display(pd.concat((df1,df2),axis=1))
# join参数指定连接方式,inner显示公共内容,outer显示所有的内容
# df1 = pd.DataFrame(np.arange(1,10).reshape(3,3))
# df2 = pd.DataFrame(np.arange(10,19).reshape(3,3),columns=[1,2,3])
# display(df1,df2)
# display(pd.concat((df1,df2),join='outer'))
# keys观察新的DataFrame中数据的来源
# df1 = pd.DataFrame(np.arange(1,10).reshape(3,3))
# df2 = pd.DataFrame(np.arange(10,19).reshape(3,3),columns=[1,2,3])
# display(pd.concat((df1,df2),keys=['df1','df2']))
# 通过join_axes指定要保留的索引
# df1 = pd.DataFrame(np.arange(1,10).reshape(3,3))
# df2 = pd.DataFrame(np.arange(10,19).reshape(3,3),columns=[1,2,3])
# display(pd.concat((df1,df2),join_axes=[df2.columns]))
# ignore_index=True 忽略之前的索引,重新创建连续的索引
df1 = pd.DataFrame(np.arange(1,10).reshape(3,3))
df2 = pd.DataFrame(np.arange(10,19).reshape(3,3),columns=[1,2,3])
display(pd.concat((df1,df2),ignore_index=True))
In [ ]:
# 数据库内连接步骤: 1 数据组合 2 根据等值条件显示
# DataFrame merge连接步骤:1 数据组合 2 根据等值条件显示
# 列名都相同,且列值也相同
# df1 = pd.DataFrame(np.array([[1,2],[3,4]]))
# df2 = pd.DataFrame(np.array([[1,2],[3,4]]))
# display(df1,df2)
# display(df1.merge(df2))
# 列名都相同,同名列存一个一个不相等值
# df1 = pd.DataFrame(np.array([[1,2,3],[3,4,5]]))
# df2 = pd.DataFrame(np.array([[1,2,4],[3,4,6]]))
# display(df1,df2)
# display(df1.merge(df2))
# 列名存在不同
# df1 = pd.DataFrame(np.array([[1,2,3],[3,4,5]]))
# df2 = pd.DataFrame(np.array([[1,2,4],[3,4,6]]),columns=[0,1,3])
# display(df1,df2)
# display(df1.merge(df2))
# how设置连接方式
# df1 = pd.DataFrame(np.array([[1,2,3],[3,4,5]]))
# df2 = pd.DataFrame(np.array([[1,2,4],[3,4,6]]))
# display(df1,df2)
# # 默认内连接,连接不上时候,不会在结果中显示
# display(df1.merge(df2,how='inner'))
# # 外连接,连接不上,2个DataFrame都会在结果中显示
# # display(df1.merge(df2,how='outer'))
# # 左连接,左边的DataFrame数据显示
# # display(df1.merge(df2,how='left'))
# # 右连接,右边的DataFrame数据显示
# display(df1.merge(df2,how='right'))
# 2个DataFrame连接时候,默认将所有的同名列索引作为连接条件
# on指定列作为连接条件,必须同时在两个DataFrame中出现
# df1 = pd.DataFrame(np.array([[1,2,3],[3,4,5]]))
# df2 = pd.DataFrame(np.array([[1,2,4],[3,4,6]]))
# display(df1,df2)
# # 默认将所有的同名列索引作为连接条件
# display(df1.merge(df2))
# # 设置Df1和Df2中0列作为连接条件
# # display(df1.merge(df2,on=0))
# # 设置Df1和Df2中0 1列作为连接条件
# display(df1.merge(df2,on=[0,1]))
# 默认根据2个Df的相同的列名等值连接
# left_on right_on 指定2个DF的等值连接列名
# df1 = pd.DataFrame(np.array([[1,2,3],[3,1,5]]))
# df2 = pd.DataFrame(np.array([[2,1,4],[3,3,6]]))
# display(df1,df2)
# display(df1.merge(df2,left_on=0,right_on=1))
# 可以通过left_index,right_index指定是否用行索引来充当连接条件。True,是;False,否
# 使用行索引作为等值连接条件,就能指定列索引作为等值连接条件--》left_index(right_index)与left_on(right_on)不能同时指定
# df1 = pd.DataFrame(np.array([[1,2,3],[3,4,5]]))
# df2 = pd.DataFrame(np.array([[1,2,4],[3,4,6]]))
# display(df1,df2)
# # Df1的行索引为0 1,df2行索引为0 1,值相等,数据可以连接
# display(df1.merge(df2,left_index=True,right_index=True))
# suffixes自定义同名列后缀
# 2个Df连接后,存在同名列,默认同名列后缀_x _y,通过suffixes自定义后缀
df1 = pd.DataFrame(np.array([[1,2,3],[3,4,5]]))
df2 = pd.DataFrame(np.array([[1,2,4],[3,4,6]]))
display(df1,df2)
# Df1的行索引为0 1,df2行索引为0 1,值相等,数据可以连接
display(df1.merge(df2,left_index=True,right_index=True,suffixes=['_df1','_df2']))
merge 原理分析:
In [426]:
# join和merge类似,都是进行两个DataFrame的连接,理解为2个步骤:1 数据组合 2 数据等值连接显示
# merge测试根据列来等值连接显示,join侧重于根据行索引来做等值连接显示
# 区别
# 1 出现同名列索引,merge会自动补后缀(_x,_y);但是join不会自动补后缀,产生错误,lsuffix和rsuffix指定后缀
# 2 merge默认进行内连接,join默认进行左外连接how参数设置连接方式
# 3 merge中on参数,指定2个DataFrame的同名列;join的on参数,仅仅指定左边(第一个)DataFrame中列,右边(第二个)DataFrame依旧是行索引
# df1 = pd.DataFrame(np.array([[1,2,3],[3,4,5]]))
# df2 = pd.DataFrame(np.array([[1,2,4],[3,4,6]]))
# display(df1,df2)
# # 出现同名列索引,merge会自动补后缀(_x,_y);但是join不会自动补后缀,产生错误,lsuffix和rsuffix指定后缀
# display(df1.join(df2,lsuffix='_df1',rsuffix='_df2'))
#
# df1 = pd.DataFrame(np.array([[1,2,3],[3,4,5]]))
# df2 = pd.DataFrame(np.array([[1,2,4],[3,4,6]]),columns=[3,4,5],index=[1,2])
# display(df1,df2)
# # merge默认进行内连接,join默认进行左外连接
# # how参数设置连接方式
# display(df1.join(df2,lsuffix='_df1',rsuffix='_df2',how='inner'))
df1 = pd.DataFrame(np.array([[1,2,3],[3,4,5]]))
df2 = pd.DataFrame(np.array([[1,2,4],[3,4,6]]),columns=[3,4,5],index=[1,2])
display(df1,df2)
# merge中on参数,指定2个DataFrame的同名列;join的on参数,仅仅指定左边(第一个)DataFrame中列,右边(第二个)DataFrame依旧是行索引
# df1中列索引为0的值 1 3,df2中行索引的值 1,2,存在相同值1
# 将df1中[1,2,3]和df2中行索引为1对应的[1,2,4]连接显示
# display(df1.join(df2,lsuffix='_df1',rsuffix='_df2',how='inner',on=0))
display(df1.join(df2,lsuffix='_df1',rsuffix='_df2',how='inner',on=2))
In [465]:
# concat merge join比较
df1 = pd.DataFrame(np.arange(1,5).reshape(2,2))
df2 = pd.DataFrame(np.arange(5,9).reshape(2,2))
display(df1,df2)
# concat数据连接时候,默认根据列索引来对齐,数据纵向连接
display(pd.concat((df1,df2)))
# concat axis=1 根据行索引对齐,进行数据水平连接
display(pd.concat((df1,df2),axis=1))
# merge和join, 都理解为2步: 1 数据水平组合在一起 2 根据等值连接条件显示。 第1步,merge和join相同
# merge默认根据所用的同名列的值,作为等值连接条件
display(df1.merge(df2))
# join默认根据行索引索引值作为等值连接条件,且左连接显示
display(df1.join(df2,how='inner',lsuffix='_df1',rsuffix='_df2'))