数据清理、转换、合并、重塑
dataframe合并
merge函数(== join,关系型数据库的核心)
(1) 数组df1和df2:
pd.merge(df1,df2) # 默认依据df1和df2的相同列索引,进行合并,相同名字的行保留;默认交集
pd.merge(df1,df2,on=‘key’) # 依据‘key’列数据,值相同的行合并,不同行舍弃;
pd.merge(df1,df2,left_on=‘key1’,right_on=‘key2’) # 对齐两数组中,key1列和key2列,值相同的行合并,不同舍弃
(2)合并的方式:‘left’-保留左表的数据值、‘right’-保留右表的数据值、‘outer’-并集、‘inner’-交集
pd.merge(df1,df2,how=‘outer’)
(3)合并后的不同列存在同名,则 suffixes 参数进行后缀命名:
pd.merge(df1,df2,on=‘key1’,how=‘outer’,suffixes=(’_x,’’_y’)) # 两数组的key2列名称变为:key2_x、key2_y
(4)合并参考列包含索引时,left_index=True、right_index=True 参数来确定是否包含索引
pd.merge(df1,df2,left_on=‘key1’,right_index=True) # 依据key1列和右数组的索引,合并数组
pd.merge(df1,df2,how=‘inner’,left_on=[‘key1’,‘key2’],right_index=True) # 依据key1和key2列,以及右数组的层次索引,合并两数组
# - merge 默认做的是inner链接,取得数据之间的交集
df1 = DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7)})
df2 = DataFrame({'key': ['a', 'b', 'd'], 'data2': range(3)})
df1key data1
0 b 0
1 b 1
2 a 2
3 c 3
4 a 4
5 a 5
6 b 6df2key data2
0 a 0
1 b 1
2 d 2pd.merge(df1, df2)# - 若无指定列,用重复值作为key(此题为a 和 b)key data1 data2
0 b 0 1
1 b 1 1
2 b 6 1
3 a 2 0
4 a 4 0
5 a 5 0#若存在两个对象列名不同,可以分别指定
df3 = DataFrame({'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7)})
df4 = DataFrame({'rkey': ['a', 'b', 'd'], 'data2': range(3)})
pd.merge(df3, df4, left_on='lkey', right_on='rkey')lkey data1 rkey data2
0 b 0 b 1
1 b 1 b 1
2 b 6 b 1
3 a 2 a 0
4 a 4 a 0
5 a 5 a 0# left, right,outer求取的是列的并集
pd.merge(df1, df2, how='outer')key data1 data2
0 b 0.0 1.0
1 b 1.0 1.0
2 b 6.0 1.0
3 a 2.0 0.0
4 a 4.0 0.0
5 a 5.0 0.0
6 c 3.0 NaN
7 d NaN 2.0#内连接 :最常见的类型。 为连接条件匹配的每对输入行生成输出行。
#左外连接 :与内连接相同,只是如果有任何行可以找到右边表中没有匹配的行,则输出一行包#含左边表中的值,其中包含NULL右边表格中的每个值。 这意味着左侧表格中的每一行在输出中至少出现一次。
#右外连接 :与左外连接相同,除了表的角色颠倒。
#全外连接 :左外连接和右外连接的组合。 两个表中的每一行都将至少出现一次输出。
#这个就超级好理解了
-Inner join of Table 1 and Table 2: - Inner join returns both tables merged only when the key (ID_STUDENT) exists in both tablesID_STUDENT STUDENT_NAME LOCKER 3 Eduardo l14 Luiz l2-Left join of Table 1 and Table 2:- Left join merges both tables with all records form table 1, in other words, there might be non-populated fields from table 2ID_ESTUDANTE NOME_ESTUDANTE LOCKER 1 Raony -2 Diogo -3 Eduardo l14 Luiz l2-Right join of table 1 and table 2:- Right join merges both tables with all records from table 2, in other words, there might be non-populated fields from table 1ID_STUDENT STUDENT_NAME LOCKER 3 Eduardo l14 Luiz l25 - l3-Outter join of table 1 and table 2:- Returns all records from both tables, in other words, theremight be non-populated fields either from table 1 or 2.ID_STUDENT STUDENT_NAME LOCKER 1 Raony -2 Diogo -3 Eduardo l14 Luiz l25 - l3
需要注意看链接键是哪个
lefth = pd.DataFrame({'key1': ['ohio', 'ohio', 'ohio', 'neveda', 'neveda'], 'key2': [2000, 2001, 2002, 2001, 2002], 'data': np.arange(5.)})
righth = pd.DataFrame(np.arange(12).reshape((6, 2)), index=[['neveda', 'neveda', 'ohio', 'ohio', 'ohio', 'ohio'], [2001, 2000, 2000, 2000, 2001, 2002]], columns=['event1', 'event2'])
lefthkey1 key2 data
0 ohio 2000 0.0
1 ohio 2001 1.0
2 ohio 2002 2.0
3 neveda 2001 3.0
4 neveda 2002 4.0righthevent1 event2
neveda 2001 0 12000 2 3
ohio 2000 4 52000 6 72001 8 92002 10 11pd.merge(lefth, righth, left_on=['key1', 'key2'], right_index=True)
#lefth 和 righth两列取交集,以左侧的key1 和 key2 作为连接键key1 key2 data event1 event2
0 ohio 2000 0.0 4 5
0 ohio 2000 0.0 6 7
1 ohio 2001 1.0 8 9
2 ohio 2002 2.0 10 11
3 neveda 2001 3.0 0 1pd.merge(lefth, righth, left_on=['key1', 'key2'], right_index=True, how='outer')
#lefth 和 righth两列取并集,以左侧的key1 和 key2 作为连接键key1 key2 data event1 event2
0 ohio 2000 0.0 4.0 5.0
0 ohio 2000 0.0 6.0 7.0
1 ohio 2001 1.0 8.0 9.0
2 ohio 2002 2.0 10.0 11.0
3 neveda 2001 3.0 0.0 1.0
4 neveda 2002 4.0 NaN NaN
4 neveda 2000 NaN 2.0 3.0#同时使用双方索引
left2 = pd.DataFrame([[1., 2.], [3., 4.], [5., 6.]], index=['a', 'c', 'e'], columns=['ohio', 'nevada'])
right2 = pd.DataFrame([[7., 8.], [9., 10.], [11., 12], [13., 14.]], index=['b', 'c', 'd', 'e'], columns=['misscouri', 'alabama'])left2ohio nevada
a 1.0 2.0
c 3.0 4.0
e 5.0 6.0right2misscouri alabama
b 7.0 8.0
c 9.0 10.0
d 11.0 12.0
e 13.0 14.0pd.merge(left2, right2, how='outer', left_index=True, right_index=True)ohio nevada misscouri alabama
a 1.0 2.0 NaN NaN
b NaN NaN 7.0 8.0
c 3.0 4.0 9.0 10.0
d NaN NaN 11.0 12.0
e 5.0 6.0 13.0 14.0left2.join(right2, how='outer')
#dataframe可以使用join,但是要求不能有重叠的列
#简单的dataframe还可以传入一组 dataframeohio nevada misscouri alabama
a 1.0 2.0 NaN NaN
b NaN NaN 7.0 8.0
c 3.0 4.0 9.0 10.0
d NaN NaN 11.0 12.0
e 5.0 6.0 13.0 14.0
轴向连接
concat函数
(1)Series类型数据
pd.concat([s1,s2,s3]) # 默认的 axis=0, 合并的数据s1、s2、s3视为行向量,形成一列数据集;
pd.concat([s1,s2,s3],axis=1) # axis=1,合并的数据s1、s2、s3视为列向量,合并为三列,不存在的值填充NaN;
pd.concat([s1,s4],axis=1,join=‘inner’) # 交集,
pd.concat([s1,s4],axis=1,join_axes=[[‘a’,‘c’,‘b’,‘e’]]) # 合并两series,并保留设定的行;
在合并后的数组中区分数据,利用层次化索引:
pd.concat([s1,s2,s3],key=[‘one’,‘two’,‘three’]) # key 为外层索引的名称
合并series数据,可以形成dataframe:
pd.merge([s1,s2,s3],axis=1,key=[‘one’,‘two’,‘three’]) # key 为列索引的名字
(2)DataFrame类型数据
pd.concat([df1,df2],axis=1,key=[,]) # 数据视为列向量,合并形成两列
pd.concat([df1,df2],axis=0,ignore_index=True) # df1和 df2视为行向量,合并,行索引重新命名0~N;
df1.combine_first(df2) # 当df1的数据中存在NaN时,使用df2中对应数据来填充。
arr = np.arange(12).reshape((3, 4))
arr
array([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11]])np.concatenate([arr, arr], axis=1)
array([[ 0, 1, 2, 3, 0, 1, 2, 3],[ 4, 5, 6, 7, 4, 5, 6, 7],[ 8, 9, 10, 11, 8, 9, 10, 11]])#concat函数将值和索引粘合s1 = pd.Series([0, 1], index=['a', 'b'])
s2 = pd.Series([2, 3, 4], index=['c', 'd', 'e'])
s3 = pd.Series([5, 6], index=['f', 'g'])
pd.concat([s1, s2, s3])a 0
b 1
c 2
d 3
e 4
f 5
g 6
dtype: int64#concat是在axis=0上工作,产生一个新的series,若引入axis=1,则结果变成一个 dataframe,则结果会在新的列上生成pd.concat([s1, s2, s3], axis=1)0 1 2
a 0.0 NaN NaN
b 1.0 NaN NaN
c NaN 2.0 NaN
d NaN 3.0 NaN
e NaN 4.0 NaN
f NaN NaN 5.0
g NaN NaN 6.0df1 = pd.DataFrame(np.arange(6).reshape(3, 2), index=['a', 'b', 'c'], columns=['one', 'two'])df2 = pd.DataFrame(5+np.arange(4).reshape(2, 2), index=['a', 'c'], columns=['three', 'four'])df1one two
a 0 1
b 2 3
c 4 5
df2three four
a 5 6
c 7 8
pd.concat([df1, df2], axis=1, keys=['level1', 'level2'])level1 level2
one two three four
a 0 1 5.0 6.0
b 2 3 NaN NaN
c 4 5 7.0 8.0#如果传入的是字典,则字典的键会被当keys选项的值
pd.concat({'level1': df1, 'level2': df2}, axis=1)level1 level2
one two three four
a 0 1 5.0 6.0
b 2 3 NaN NaN
c 4 5 7.0 8.0#层次化索引的参数,names命名轴级别
pd.concat([df1, df2], axis=1, keys=['levle1', 'level2'], names=['upper', 'lower'])
upper levle1 level2
lower one two three four
a 0 1 5.0 6.0
b 2 3 NaN NaN
c 4 5 7.0 8.0#与分析工作无关的dataframe行索引使用 ignore_index
df1 = pd.DataFrame(np.random.randn(3, 4), columns=['a', 'b', 'c', 'd'])
df2 = pd.DataFrame(np.random.randn(2, 3), columns=['b', 'd', 'a'])
df1a b c d
0 -1.656672 -0.011800 -0.595921 -0.825796
1 -1.616126 0.738394 0.564809 1.327172
2 -0.044003 0.225758 0.591922 -0.696901df2b d a
0 0.358382 1.267985 0.484044
1 -3.066617 1.062455 -0.753830pd.concat([df1, df2], ignore_index=True)a b c d
0 -1.656672 -0.011800 -0.595921 -0.825796
1 -1.616126 0.738394 0.564809 1.327172
2 -0.044003 0.225758 0.591922 -0.696901
3 0.484044 0.358382 NaN 1.267985
4 -0.753830 -3.066617 NaN 1.062455
合并重叠数据
a = Series([np.nan, 2.5, np.nan, 3.5, 4.5, np.nan], index=['f', 'e', 'd', 'c', 'b', 'a'])f NaN
e 2.5
d NaN
c 3.5
b 4.5
a NaN
dtype: float64b = Series(np.arange(len(a), dtype=np.float64), index=['f', 'e', 'd', 'c', 'b', 'a'])f 0.0
e 1.0
d 2.0
c 3.0
b 4.0
a 5.0
dtype: float64
#令b的最后一个值为 NAN
b[-1] = np.nanf 0.0
e 1.0
d 2.0
c 3.0
b 4.0
a NaN
dtype: float64b[:-2].combine_first(a[2:])a NaN
b 4.5
c 3.0
d 2.0
e 1.0
f 0.0
dtype: float64#combine_first特点
#两组数据,当前一组nan时,后组填充。
#合并后组比前组少的数据
df1 = pd.DataFrame({'a': [1., np.nan, 5., np.nan], 'b': [np.nan, 2., np.nan, 6.], 'c': range(2, 18, 4)})
df1#以第一个参数为起点,第三个参数为步长,截止到第二个参数之前的不包括第二个参数的数据序列a b c
0 1.0 NaN 2
1 NaN 2.0 6
2 5.0 NaN 10
3 NaN 6.0 14df2 = pd.DataFrame({'a': [5., 4., np.nan, 3., 7.], 'b': [np.nan, 3., 4., 6., 8.]})
df2a b
0 5.0 NaN
1 4.0 3.0
2 NaN 4.0
3 3.0 6.0
4 7.0 8.0df1.combine_first(df2)
#combine_first特点
#两组数据,当前一组nan时,后组填充。
#合并后组比前组少的数据a b c
0 1.0 NaN 2.0
1 4.0 2.0 6.0
2 5.0 4.0 10.0
3 3.0 6.0 14.0
4 7.0 8.0 NaN
重塑和轴向旋转
数据重塑(Dataframe和Series的数据转换:unstack和stack)
1) result=data.stack() # data 数组转化为 Series类型,层次化索引;
result2 = result.unstack() # 默认:以外层索引为行索引,内层为列索引,形成DataFrame;
result.unstack(0) # 以原行索引为 列索引
result.unstack(‘name’) # 以索引名称对应的索引作为行索引
2) unstack() 形成数组,会引入缺失值NaN;
stack() 形成Series , 会省去缺失值NaN,data.stack(dropna=False),不省去NaN。
1 层次化索引
在一个轴上拥有多个索引,能以低纬度处理高纬度问题;
)层次化索引的赋值:data=pd.Series(np.random.randn(4),index=[[‘a’,‘a’,‘b’,‘b’],[1,2,1,3]])
)层次化索引的子集提取:
data[‘b’] # 外层索引提取
data[‘a’:‘b’] # 索引直接提取,只能提取连续索引
data.loc[[‘a’,‘b’]] # 多个单独的索引提取,利用loc函数
data.loc[‘a’:‘b’,1:3] # loc函数也可以提取连续的多个索引值
data.loc[:,1] # 利用loc函数,依据内层索引来选取子集
)层次化索引转化为DataFrame数组:unstack( )和stack( )
data.unstack() # 多层索引转化为数组,外层索引为index,内层索引为columns;
data.unstack().stack() # 数组,还原成 多层索引Series
)层次化索引中,不同索引轴的转换:(data.index.names=[‘name1’,‘name2’])
data.swaplevel(‘name1’,‘name2’) # 利用索引的名称进行转换,需要提前命名
data.swaplevel(0,1) # 利用索引的代号,进行转换
)层次化索引的排序:
data.sort_index(level=0) # 依据外层索引进行排序(第一列索引)
)合并相同索引名称:
data.sum(level=‘name1’) # name1中,相同索引值得数据求和,形成新的数组
)在DataFrame数组中,其中两列以上的数据作为索引
frame.set_index([‘c’,‘d’],drop=False) # 以c、d两列,作为层次化索引的值,默认去掉两列;可通过drop参数,保留两列
frame.reset_indx( ) # 层次化索引,被还原到数组中
stack()
# 参数
DataFrame.stack(self,level = -1,dropna = True )
#参数说明
level: 默认为-1,即列索引的最后一级
dropna: 布尔值,默认为True,即是否删除具有缺失值的行# 我们创建一个多级列的列子来说明stack()
import pandas as pd
import numpy as np# 这里分别使用两种方法生成多层索引第一种是元组法,第二种是列表法
col = pd.MultiIndex.from_tuples([('weight','kg'),('weight','ton'),('height','cm'),('height','m')])
dex = pd.MultiIndex.from_arrays([['China','China','USA','USA'],['Tom','Jack','Arfra','Switch']])# 创建一个我们需要用到的DataFrame
data = pd.DataFrame([[None,0.08,180,1.8],[70,0.07,160,1.6],[50,0.05,170,1.7],[55,0.055,175,1.75]],index=dex,columns=col)# 我们先来看一下DataFrame
dataweight heightkg ton cm m
China Tom NaN 0.080 180 1.80Jack 70 0.070 160 1.60
USA Arfra 50 0.050 170 1.70Switch 55 0.055 175 1.75#1. 默认情况,即level=-1,dropna=True
result = data.stack()
resultresult:height weight
China Tom cm 180.00 NaNm 1.80 NaNton NaN 0.080Jack cm 160.00 NaNkg NaN 70.000m 1.60 NaNton NaN 0.070
USA Arfra cm 170.00 NaNkg NaN 50.000m 1.70 NaNton NaN 0.050Switch cm 175.00 NaNkg NaN 55.000m 1.75 NaNton NaN 0.055#从结果可以看出来,由于level=-1,因此将第二层列索引透视到了行,而且由于dropna=True,与之对应的透视之后的Tom的kg这一行数据被drop掉。#2. level=0,dropna=False的情况下result = data.stack(level=0,dropna=False)
resultresult:cm kg m ton
China Tom height 180.0 NaN 1.80 NaNweight NaN NaN NaN 0.080Jack height 160.0 NaN 1.60 NaNweight NaN 70.0 NaN 0.070
USA Arfra height 170.0 NaN 1.70 NaNweight NaN 50.0 NaN 0.050Switch height 175.0 NaN 1.75 NaNweight NaN 55.0 NaN 0.055#从结果可以看出来,由于level=0,因此将第一层列索引透视到了行,而且由于dropna=False,并没有drop掉缺失行,其实,这里就算dropna=True,也不会drop掉任何行。因为缺失值在第二次索引kg上,而我们将第一层索引透视到行上,因此这里不会有drop
unstack()
#含义:
#该操作会将行中数据透视到列
#参数说明
DataFrame.unstack(self,level = -1,fill_value = None)
#参数说明
level: 默认为-1,即行索引的最后一级
fill_value: 如果unstack 生成,则用此值替换NaN
缺失值#1. 默认情况,即level=-1result = data.unstack()
resultresult:weight heightkg ton cm mArfra Jack Switch Tom Arfra Jack Switch Tom Arfra Jack Switch Tom Arfra Jack Switch Tom
China NaN 70.0 NaN NaN NaN 0.07 NaN 0.08 NaN 160.0 NaN 180.0 NaN 1.6 NaN 1.8
USA 50.0 NaN 55.0 NaN 0.05 NaN 0.055 NaN 170.0 NaN 175.0 NaN 1.7 NaN 1.75 NaN#data.unstack(0)#level=0,fill_value='缺失’的情况result = data.unstack(level=0,fill_value='缺失')
resultresult:weight heightkg ton cm mChina USA China USA China USA China USA
Arfra 缺失 50 缺失 0.05 缺失 170 缺失 1.7
Jack 70 缺失 0.07 缺失 160 缺失 1.6 缺失
Switch 缺失 55 缺失 0.055 缺失 175 缺失 1.75
Tom NaN 缺失 0.08 缺失 180 缺失 1.8 缺失
移除重复数据
data = pd.DataFrame({'k1': ['one', 'two']*3 + ['two'], 'k2': [1, 1, 2, 3, 3, 4, 4]})
datak1 k2
0 one 1
1 two 1
2 one 2
3 two 3
4 one 3
5 two 4
6 two 4#判断前面出现的行是否有重复行
data.duplicated()
0 False
1 False
2 False
3 False
4 False
5 False
6 True
dtype: booldata.drop_duplicates()
#会返回dataframe,重复的数组会标记为false
k1 k2
0 one 1
1 two 1
2 one 2
3 two 3
4 one 3
5 two 4data['v1'] = range(7)
datak1 k2 v1
0 one 1 0
1 two 1 1
2 one 2 2
3 two 3 3
4 one 3 4
5 two 4 5
6 two 4 6data.drop_duplicates(['k1'])
#只希望过滤k1k1 k2 v1
0 one 1 0
1 two 1 1data.drop_duplicates(['k1', 'k2'], keep='last')
#默认保留第一个出现得值组合,加了last,则保留最后一个k1 k2 v1
0 one 1 0
1 two 1 1
2 one 2 2
3 two 3 3
4 one 3 4
6 two 4 6
利用函数或者映射进行数据转换
data = pd.DataFrame({'food':['bacon','pulled pork','bacon','Pastrami','corned beef','Bacon','pastrami','honey ham','nova lox'],'ounces':[4,3,12,6,7.5,8,3,5,6]})datafood ounces
0 bacon 4.0
1 pulled pork 3.0
2 bacon 12.0
3 Pastrami 6.0
4 corned beef 7.5
5 Bacon 8.0
6 pastrami 3.0
7 honey ham 5.0
8 nova lox 6.0meat_to_animal = {'bacon' : 'pig','pulled pork' : 'pig',"pastrami" : 'cow',"corned beef" : 'cow',"honey ham" : 'pig','nova lox' : "salmin"
}#添加一列表示肉类食物来源的动物类型--映射lowercased = data['food'].str.lower()#因为有的大写有的小写,统一小写 str.lower
lowercased
0 bacon
1 pulled pork
2 bacon
3 pastrami
4 corned beef
5 bacon
6 pastrami
7 honey ham
8 nova lox
Name: food, dtype: objectdata['anaimal'] = lowercased.map(meat_to_animal)#映射到动物
datafood ounces anaimal
0 bacon 4.0 pig
1 pulled pork 3.0 pig
2 bacon 12.0 pig
3 Pastrami 6.0 cow
4 corned beef 7.5 cow
5 Bacon 8.0 pig
6 pastrami 3.0 cow
7 honey ham 5.0 pig
8 nova lox 6.0 salmindata['food'].map(lambda x: meat_to_animal[x. lower()]) #map是一种实现元素级转换以及其他数据清理工作的便携方式
0 pig
1 pig
2 pig
3 cow
4 cow
5 pig
6 cow
7 pig
8 salmin
Name: food, dtype: object
替换值
data = pd.Series([1.,999.,2.,-999.,-1000.,3.])
# 0 1.0
# 1 999.0
# 2 2.0
# 3 -999.0
# 4 -1000.0
# 5 3.0
# dtype: float64data.replace(-999.,np.nan)#将-999替换为na
# 0 1.0
# 1 999.0
# 2 2.0
# 3 NaN
# 4 -1000.0
# 5 3.0
# dtype: float64data.replace([-999,-1000.],np.nan#将-999 和 -1000都替换为na
# 0 1.0
# 1 999.0
# 2 2.0
# 3 NaN
# 4 NaN
# 5 3.0
# dtype: float64data.replace([-999,-1000.],[np.nan,0])#将多个值替换为不同的值
# 0 1.0
# 1 999.0
# 2 2.0
# 3 NaN
# 4 0.0
# 5 3.0
# dtype: float64
重命名轴索引
data = pd.DataFrame(np.arange(12).reshape((3,4)),index = ['Ohio','Colorado','New York'],columns = ['one','two','three','four'])one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
New York 8 9 10 11transform = lambda x: x[:4].upper()
data.index.map(transform)#大写Index(['OHIO', 'COLO', 'NEW '], dtype='object')data.index = data.index.map(transform)
dataone two three four
OHIO 0 1 2 3
COLO 4 5 6 7
NEW 8 9 10 11data.rename(index=str.title, columns=str.upper)#列名大写ONE TWO THREE FOUR
Ohio 0 1 2 3
Colo 4 5 6 7
New 8 9 10 11data.rename(index={'OHIO': 'INDIANA'}, columns={'three': 'peekaboo'})#将行名和列名分别替换one two peekaboo four
INDIANA 0 1 2 3
COLO 4 5 6 7
NEW 8 9 10 11data.rename(index={'OHIO': 'INDIANA'}, inplace=True)#rename可以复制dataframe并且对其索引和列标签进行复制,如果希望就地修改数据集(修改数据源),传入 inplace=True
dataone two three four
INDIANA 0 1 2 3
COLO 4 5 6 7
NEW 8 9 10 11
离散化和面元划分
连续数据常常被离散化或拆分为“面元”。
#(1)假设有一组人员数据,希望将它们划分为不同的年龄组:
ages = [20,22,25,27,21,23,37,31,61,45,41,32]
#接下来将这些数据划分为:“18到25”、“26到35”、36到60、以及“60以上” 使用cut函数 左开右闭bins = [18,25,35,60,100]
cats = pd.cut(ages,bins)
cats
Out[5]:
[(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]]
Length: 12
Categories (4, interval[int64]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]#(2)pandas返回的是一个特殊的Categorical对象,可以将其看作一组并表示面元名称的字符串。实际上,它含有一个表示不同分类名称的codes数组以及一个为年龄数据进行标号的categories属性:cats.codes
Out[7]: array([0, 0, 0, 1, 0, 0, 2, 1, 3, 2, 2, 1], dtype=int8)cats.categories
Out[9]:
IntervalIndex([(18, 25], (25, 35], (35, 60], (60, 100]],closed='right',dtype='interval[int64]')pd.value_counts(cats)
Out[10]:
(18, 25] 5
(35, 60] 3
(25, 35] 3
(60, 100] 1
dtype: int64#(3)哪边闭端可以通过right=False进行修改
pd.cut(ages,bins,right=False)
Out[12]:
[[18, 25), [18, 25), [25, 35), [25, 35), [18, 25), ..., [25, 35), [60, 100), [35, 60), [35, 60), [25, 35)]#(4)自定义面元名称,将labels选项设置为一个列表或数组即可:
pd.cut(ages,bins,labels=group_names)
Out[14]:
[Youth, Youth, Youth, YoungAdult, Youth, ..., YoungAdult, Senior, MiddleAged, MiddleAged, YoungAdult]
Length: 12
Categories (4, object): [Youth < YoungAdult < MiddleAged < Senior]#(5)如果向cut传入的是面元的数量而不是确切的面元边界,则它会根据数据的最小值和最大值计算等长面元。data = np.random.rand(20)
pd.cut(data,4,precision=2)
Out[16]:
[(0.29, 0.5], (0.29, 0.5], (0.5, 0.71], (0.5, 0.71], (0.71, 0.91], ..., (0.29, 0.5], (0.71, 0.91], (0.084, 0.29], (0.71, 0.91], (0.71, 0.91]]
Length: 20
Categories (4, interval[float64]): [(0.084, 0.29] < (0.29, 0.5] < (0.5, 0.71] < (0.71, 0.91]]#(6)qcut根据样本分位数对数据进行面元划分。根据数据的分布情况,cut可能无法使各个面元中含有相同数量的数据点。而qcut由于使用的是样本分位数,因此可以得到大小基本相等的面元:
data = np.random.randn(1000)
cats = pd.qcut(data,4)
cats
Out[21]:
[(-0.672, -0.051], (0.643, 2.886], (-0.051, 0.643], (-0.051, 0.643], (-0.672, -0.051], ..., (-3.318, -0.672], (-0.672, -0.051], (-0.672, -0.051], (-0.051, 0.643], (0.643, 2.886]]
Length: 1000
Categories (4, interval[float64]): [(-3.318, -0.672] < (-0.672, -0.051] < (-0.051, 0.643] < (0.643, 2.886]]pd.value_counts(cats)
Out[22]:
(0.643, 2.886] 250
(-0.051, 0.643] 250
(-0.672, -0.051] 250
(-3.318, -0.672] 250
dtype: int64#跟cut一样,也可以设置自定义的分位数(0到1之间的数值,包含端点)
pd.qcut(data,[0,0.1,0.5,0.9,1.])
Out[23]:
[(-1.244, -0.051], (1.313, 2.886], (-0.051, 1.313], (-0.051, 1.313], (-1.244, -0.051], ..., (-1.244, -0.051], (-1.244, -0.051], (-1.244, -0.051], (-0.051, 1.313], (1.313, 2.886]]
Length: 1000
Categories (4, interval[float64]): [(-3.318, -1.244] < (-1.244, -0.051] < (-0.051, 1.313] < (1.313, 2.886]]
检测和过滤异常值
(1)异常值的过滤或变换运算在很大程度上其实就是数组运算
np.random.seed(112345)
data = DataFrame(np.random.randn(1000,4))
data.describe()
Out[26]: 0 1 2 3
count 1000.000000 1000.000000 1000.000000 1000.000000
mean 0.009368 0.023849 0.009318 -0.054212
std 1.006971 1.005607 1.016713 0.966702
min -3.387772 -3.089641 -3.067449 -3.260214
25% -0.687284 -0.699800 -0.672709 -0.718028
50% 0.010435 0.014086 0.003922 -0.019851
75% 0.693247 0.718440 0.683285 0.587810
max 3.278995 3.478712 3.377368 2.991915(2)找出某列中绝对值大小超过3的值
col = data[3]
col[np.abs(col)>3]
Out[29]:
49 -3.260214
441 -3.094784
680 -3.138965
968 -3.033843
Name: 3, dtype: float64(3)选出全部含有“超过3或-3的值”的行,你可以利用布尔型DataFrame以及any方法:data[(np.abs(data)>3).any(1)]
Out[30]: 0 1 2 3
22 -0.698743 -0.398163 3.377368 -0.997289
49 0.630168 -1.012116 -2.054247 -3.260214
204 -0.749329 2.167998 3.334472 1.244409
213 1.742405 3.338408 -1.064566 1.663745
441 0.092096 1.289854 0.900876 -3.094784
449 -2.197054 0.190983 -3.067449 -1.476711
471 3.278995 1.343816 -1.614158 1.834566
505 -3.387772 0.219453 1.050503 -0.983548
602 -0.045450 3.478712 1.506986 0.819802
651 -3.016390 1.176740 2.850093 -2.214279
680 -0.491598 0.812230 2.226199 -3.138965
711 0.230303 0.133684 3.037248 -0.965220
849 0.692234 -3.089641 0.567583 -0.029900
968 -0.716044 0.840879 -1.174742 -3.033843(4)根据这些条件,即可轻松地对值进行设置。下面代码可以将值限制在区间-3到3以内
data[np.abs(data)>3] = np.sign(data)*3
data.describe()
Out[32]: 0 1 2 3
count 1000.000000 1000.000000 1000.000000 1000.000000
mean 0.009493 0.023122 0.008636 -0.053684
std 1.004817 1.002737 1.014176 0.965040
min -3.000000 -3.000000 -3.000000 -3.000000
25% -0.687284 -0.699800 -0.672709 -0.718028
50% 0.010435 0.014086 0.003922 -0.019851
75% 0.693247 0.718440 0.683285 0.587810
max 3.000000 3.000000 3.000000 2.991915
排列和随机采样
(1)numpy.random.permutation实现对Series或DataFrame的行的排列工作。通过需要排列的轴的长度调用permutation,可产生一个表示新顺序的整数数组df = DataFrame(np.arange(5*4).reshape(5,4))
sampler = np.random.permutation(5)
sampler
Out[35]: array([1, 3, 0, 2, 4])(2)基于ix的索引操作或take函数中使用该数组df
Out[36]: 0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
3 12 13 14 15
4 16 17 18 19df.take(sampler)
Out[37]: 0 1 2 3
1 4 5 6 7
3 12 13 14 15
0 0 1 2 3
2 8 9 10 11
4 16 17 18 19(3)如果不想用替换的方式选取子集,则可以使用permutation:从permutation返回的数组中切下前K个元素,其中K为期望的子集大小。df.take(np.random.permutation(len(df))[:3])
Out[38]: 0 1 2 3
0 0 1 2 3
4 16 17 18 19
1 4 5 6 7(4)通过替换的方式产生样本,最快的方式是通过np.random.randint得到一组随机整数:bag = np.array([5,7,-1,6,4])
sampler = np.random.randint(0,len(bag),size=10)
sampler
Out[41]: array([1, 4, 2, 0, 3, 0, 2, 2, 3, 3])
draws = bag.take(sampler)
draws
Out[43]: array([ 7, 4, -1, 5, 6, 5, -1, -1, 6, 6])
计算指标/哑变量
一种常用于统计建模或机器学习的转换方式是:将分类变量转换为“哑变量矩阵”或指标矩阵。如果DataFrame的某一列中含有k个不同的值,则可以派生出一个K列矩阵或DataFrame(其值全为1或0)。pandas有一个get_dummies函数可以实现该功能
df = DataFrame({'key':['b','b','a','c','a','b'],'data1':range(6)})
pd.get_dummies(df['key'])
Out[45]: a b c
0 0 1 0
1 0 1 0
2 1 0 0
3 0 0 1
4 1 0 0
5 0 1 0(2)get_dummies的prefix参数可以实现可以给指标DataFrame的列加上一个前缀,以便能够跟其他数据进行合并
dummies = pd.get_dummies(df['key'],prefix='key')
df_with_dummy = df[['data1']].join(dummies)
df_with_dummy
Out[48]: data1 key_a key_b key_c
0 0 0 1 0
1 1 0 1 0
2 2 1 0 0
3 3 0 0 1
4 4 1 0 0
5 5 0 1 0
数据清理、转换、合并、重塑相关推荐
- python输出矩阵图片_Python图片与其矩阵数据互相转换
程序 # coding=gbk from PIL import Image import numpy as np # import scipy import matplotlib.pyplot as ...
- dplyr包功能(数据清理、过滤、合并R实现)
目录 去除重复项 选取随机样本 变量重命名 select()函数 filter()函数 summarise()函数 arrange()函数 group_by() 函数 mutate()函数 join( ...
- uni-app清理缓存数据_数据清理-从哪里开始?
uni-app清理缓存数据 It turns out that Data Scientists and Data Analysts will spend most of their time on d ...
- 【Python实战】数据预处理(数据清理、集成、变换、归约)
[Python实战]数据预处理 前言 数据预处理概述 数据清理 异常数据处理 1.异常数据分析 2.异常数据处理方法 缺失值处理 噪声数据处理 数据集成 1.实体识别 2.冗余属性 3.数据不一致 数 ...
- 数据科学的原理与技巧 四、数据清理
四.数据清理 原文:DS-100/textbook/notebooks/ch04 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 数据以多种格式出现,并且在分析的实用性方面差别很 ...
- 数据预处理+数据清理
1.概述 实际的数据库极易受噪声.缺失值和不一致数据的侵扰,因为数据库太大,并且多半来自多个异种数据源.低质量的数据将会导致低质量的挖掘结果.有大量的数据预处理技术: - - 数据清理:可以用来清楚数 ...
- 数据预处理—-(数据探索、数据清理、数据集成、数据规约、数据变换)
数据挖掘概念与技术 定义挖掘目标–>数据取样–>数据探索–>数据预处理–>挖掘建模–>模型评价 第一章.数据 挖掘的数据类型:时间序列,序列,数据流,时间空间数据,多媒体 ...
- 大数据中数据清理怎么做的_针对不完整数据的大数据清洗方法与流程
本发明属于大数据清洗技术领域,涉及一种针对不完整数据的大数据清洗方法. 背景技术: 随着信息化的进展,企业内部积累了大量的电子数据,这些数据对企业非常重要.但由于各种原因,导致企业现有系统数据库中存在 ...
- 数据预处理_数据清理
1.概述 实际的数据库极易受噪声.缺失值和不一致数据的侵扰,因为数据库太大,并且多半来自多个异种数据源.低质量的数据将会导致低质量的挖掘结果.有大量的数据预处理技术: - - 数据清理:可以用来清楚数 ...
最新文章
- hibernate延迟加载lazy的原理,以及为什么session关闭会报错
- 前端模块化开发学习之gulpbrowserify篇
- boost的chrono模块时间间隔的测试程序
- [centos][ntp][administrator] chrony ntp
- nginx生成自定义证书
- IPM: 使用代码删除Acquisition contract上的IP Product
- 怎样用计算机添加文章标题,计算机论文题目怎么定-易指做帮写网
- ip地址转换pta题目_PTA「实验2-3-5 输出华氏-摄氏温度转换表」
- java通过匹配合并数据(数据预处理)
- Docker学习总结(15)——通过 Docker 搭建RocketMQ
- 谷歌推出理解神经网络的新方法SVCCA | NIPS论文+代码
- 背包笔记及Java实现
- java大于0的正则_求一个 大于0且小于1 的正则表达式(无论几位小数)
- svn汉化插件安装步骤
- 数据结构(郝斌课程内容概述)
- 怎样用计算机制作漫画,用电脑绘制漫画需要些什么?步骤是什么?
- Windows提权基本原理
- simnow账户无法使用,simnow账户修改密码
- mysql jdbc execute_MySQL JDBC Statement.executeBatch实践问题
- Cobalt Strike使用详解