1.合并数据集
出发点:数据集的合并或连接是通过一个或多个键将行链接起来的
df1 = DataFrame({'key':['b','b','c','d','a','a'],'data1':range(6)})
# key data
# 0 b 0
# 1 b 1
# 2 c 2
# 3 d 3
# 4 a 4
# 5 a 5
df2 = DataFrame({'key':['b','c','d','a'],'data2':range(4)})
#在不指定按照哪个列名进行合并的时候,默认按照重叠列进行合并
pd.merge(df1,df2) #根据不同df的键合并
# key data1 data2
# 0 b 0 0
# 1 b 1 0
# 2 c 2 1
# 3 d 3 2
# 4 a 4 3
# 5 a 5 3
pd.merge(df1,df2,on='key') #按照key这一列进行合并
#如果两个数据集的列名不同,也可以指定
pd.merge(df1,df2,left_on = 'lkey',right_on = 'rkey')
#上面的连接时采用的内连接的方式,就是取key的交集,可以指定为outer的方式,取key的并集
pd.merge(df1,df2,how='outer') #外连接方式
pd.merge(df1,df2,on=['key1','key2']) #多个键进行合并
pd.merge(left,right,left_on = 'key',right_index = True) #按照第一个数据集的key和第二个数据集的索引进行连接
#根据相似索引合并数据集
left = DataFrame([[1,2],[3,4],[5,6]],index = ['a','c','e'],columns = ['ohio','nevada'])
right = DataFrame([[7,8],[9,10],[11,12],[13,14]],index = ['b','c','d','e'],columns = ['Missi','Alabama'])
left.join(right,how='outer') #根据相同的索引进行合并
#当然也可以使用key进行join
df1.join(df2,on='key')
2.按照轴进行合并
arr = np.arange(12).reshape(3,4)
np.concatenate([arr,arr],axis =1) #相当于进行行的拼接 axis=0就是进行列的拼接
# 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]])
3.数据重塑和轴向旋转
data = DataFrame(np.arange(6).reshape(2,3),index = pd.Index(['ohio','Colorado'],name = 'state'),columns = pd.Index(['one','two','three'],name = 'number'))
# number one two three
# state
# ohio 0 1 2
# Colorado 3 4 5
#使用stack将数据的列旋转为行
data.stack()
# state number
# ohio one 0
# two 1
# three 2
# Colorado one 3
# two 4
# three 5
# 使用unstack将数据的行旋转为列
data.stack().unstack()
一般情况下数据是按照上图的方式排列的,每一行可以看作是一个实体,但是我们可能希望按照dataframe的方式进行查询,因此可以进行转换。
pivoted = ldata.pivot('date','item','value')
#第一个参数为用作行索引的列名,第二个参数是用作列索引的列名,最后一个参数是用于填充新的df数据列的列名。
pivoted.head()
转化后的结果如图:
如果有多个需要填充的列(如上图),直接忽略第三个参数就可以
pivoted2 = ldata2.pivot('date','item')
# pivot可以看作是一种快捷方式,其实相当于
pivoted = ldata2.set_index(['date','item']).unstack('item')
# 不太懂stack和unstack什么意思,先记下来
这样就可以转化为如图的带有层次化索引的数据形式
4.数据转换
# 数据去重
#判断每行是否重复
data = DataFrame({'k1':['one']*3+['two']*4,'k2':[1,1,2,3,3,4,4]})
data
# k1 k2
# 0 one 1
# 1 one 1
# 2 one 2
# 3 two 3
# 4 two 3
# 5 two 4
# 6 two 4
data.duplicated() #根据全部列判断行是否重复,返回一个bool型的series
data.drop_duplicates() #删除重复行
#如果只是想根据某些列判断行是否重复,只需要指定想要判断的列名
data['v1'] = range(7)
data.duplicated(['v1'])
data.drop_duplicated(['k1'])
# 利用函数或映射进行数据转换
data = DataFrame({'food':['bacon','pulled pork','pastrami'],'ounces':[1,2,3]})
meat_to_animal = {'bacon':'pig','pulled pork':'pig','pastrami':'cow'}
data['animals'] = data['food'].map(str.lower).map(meat_to_animal) #str.lower是为了把food都转为小写字母,然后再通过meat_to_animal映射为动物名称
# 上述映射也可以用一个lambda函数来完成
data['animal'] = data['food'].map(lambda x:meat_to_animal[x.lower()])
# 替换
data.replace(-999,np.nan) #使用np.nan替换-999
data.replace([-999,-1000],np.nan) #同时替换多个词
data.replace([-999,-1000],[np.nan,0]) #对不同的词进行不同的替换
#数据离散化和面元划分
ages = [20,22,25,27,21,23,37,31,61,45,41,32]
bin = [18,25,35,60,100] #相当于分界线
cats = pd.cut(ages,bin) #按照bin对ages进行分组
cats
#返回的首先是ages中每个元素属于的组,最后一行是按照bin分得的组
# [(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]]
group_names = ['youth','youngadult','middleage','senior']
cats = pd.cut(ages,bin,labels = group_names) #labels表示每个组的标签
# 如果没有给定bin(就是明确的界限),那么cut函数会按照组数和数据地最大值与最小值等长地划分
data = np.random.rand(20)
pd.cut(data,4,precision = 2) #4是组数,2是小数点两位
pd.qcut(data,4) #按照四分位数进行分组
pd.qcut(data,[0,0.1,0.5,0.9]) #按照自己设定地分位数进行分组
5.字符串对象
val = 'a,b, guido'
# 根据,对val进行拆分
val.split(',')
# 去除字符串两端的空格
pieces = [x.strip() for x in val.split(',')]
# 将一个list转化为字符串,每个list元素之间的间隔符为::
str = '::'.join(pieces) #a::b::guido
# 字符串的替代函数
str.replace('::',' ')
6.正则表达式
可以在正则表达式的字符串前加r,避免对这个字符不必要的转义。例如r’\t’ 那么查找的就是\t而不是t
# 一个或多个空白符
\s+
re非常玄妙,自由探索吧…