当前位置: 首页>编程语言>正文

Python merge 和 join的区别 merge在python

1、合并数据

①、多对一合并

我们需要用到pandas中的merge函数,merge函数默认情况下合并的是两个数据集的交集(inner连接),当然还有其他的参数:

how里面有inner、outer、left、right,四个参数可以选择,分别代表:交集,并集,参与合并的左侧DataFrame,以及右侧



当列名对象相同时:
df1=pd.DataFrame({'key':['a','c','a','b','a','c','b','c'],'data1':range(8)})
df2=pd.DataFrame({'key':['a','b','d'],'data2':range(3)})
pd.merge(df1,df2,on='key')
返回
     key  data1  data2
0    a    0    0
1    a    2    0
2    a    4    0
3    b    3    1
4    b    6    1
当列名对象不同时:
df1=pd.DataFrame({'lkey':['a','c','a','b','a','c','b','c'],'data1':range(8)})
df2=pd.DataFrame({'rkey':['a','b','d'],'data2':range(3)})
pd.merge(df1,df2,left_on='lkey',right_on='rkey',how=‘outer’)
返回为
    
     lkey   data1 rkey    data2
0    a    0.0    a    0.0
1    a    2.0    a    0.0
2    a    4.0    a    0.0
3    c    1.0    NaN    NaN
4    c    5.0    NaN    NaN
5    c    7.0    NaN    NaN
6    b    3.0    b    1.0
7    b    6.0    b    1.0
8    NaN    NaN    d    2.0



②、多对多合并



df1=pd.DataFrame({'key':['b','c','b','a','b','a'],'data1':range(6)})
df2=pd.DataFrame({'key':['a','a','c','b','d'],'data2':range(5)})
pd.merge(df1,df2,on='key',how='right')
返回为
      key  data1 data2
0    b    0.0    3
1    b    2.0    3
2    b    4.0    3
3    c    1.0    2
4    a    3.0    0
5    a    5.0    0
6    a    3.0    1
7    a    5.0    1
8    d    NaN    4



多对多合并产生的是行的笛卡尔积,即df1有2个a,df2有2个a,并集会产生4个a

当需要根据多个键进行合并时,只要传入一个列名组成的列表就可以。

在合并运算时,需要对重复列名的处理,suffixes函数可以指定附加到左右两个DataFrame对象的重复列名上的字符串

2、索引上的合并

当Dataframe中的连接键位于索引中时,可以利用merge参数的left_index=True或right_index=True来表明索引应该被用作连接键:



left1=pd.DataFrame({'key':['a','b','c','a','b','a'],'value':range(6)})
right1=pd.DataFrame({'gvalue':[2,3.5]},index=['b','c'])
pd.merge(left1,right1,left_on='key',right_index=True)
返回为
     key   value    gvalue
1    b    1    2.0
4    b    4    2.0
2    c    2    3.5



当出现层次化索引的数据时,需要以列表的形式指明用作合并键的多个列



left=pd.DataFrame({'key1':['A','B','C','A','C','A'],
                   'key2':[2011,2012,21011,2012,2013,2011],
                   'data':np.arange(6)})
right=pd.DataFrame(np.arange(12).reshape((6,2)),
                   index=[['A','B','C','C','C','B'],
                          [2011,2012,2011,2011,2011,2012]],
                   columns=['event1','event2'])
pd.merge(left,right,left_on=['key1','key2'],right_index=True,how='outer')
返回为
     key1   key2    data event1 event2
0    A    2011    0.0    0.0    1.0
5    A    2011    5.0    0.0    1.0
1    B    2012    1.0    2.0    3.0
1    B    2012    1.0    10.0    11.0
2    C    21011    2.0    NaN    NaN
3    A    2012    3.0    NaN    NaN
4    C    2013    4.0    NaN    NaN
5    C    2011    NaN    4.0    5.0
5    C    2011    NaN    6.0    7.0
5    C    2011    NaN    8.0    9.0



当要合并两个数据集的索引时,只需要left_index=True,right_index=True

另外,DataFrame的join可以实现按索引合并,而且还可以合并多个具有相同或相似索引的DataFrame对象,而忽视之间有无重叠的列



left2=pd.DataFrame([[1.2],[3,4],[5,6],[7,8]],index=['a','b','c','d'],
                  columns=['Wang','Li'])
right2=pd.DataFrame([[9,10],[11,12],[13,14]],index=['b','c','e'],
                   columns=['Zhao','Liu'])
left2.join(right2,how='outer')
返回
     Wang    Li    Zhao    Liu
a    1.2    NaN    NaN    NaN
b    3.0    4.0    9.0    10.0
c    5.0    6.0    11.0    12.0
d    7.0    8.0    NaN    NaN
e    NaN    NaN    13.0    14.0



还可以向join传入一组DataFrame,进行索引:



other=pd.DataFrame([[6,7],[8,9],[10,11],[12,15]],index=['a','b','c','d'],
                   columns=['Sun','Qian'])
left2.join([right2,other])#默认求交集
返回为

      Wang    Li    Zhao  Liu    Sun  Qian
a    1.2    NaN    NaN    NaN     6    7
b    3.0    4.0    9.0    10.0    8    9
c    5.0    6.0    11.0   12.0   10    11
d    7.0    8.0    NaN    NaN    12    15



3、轴向连接

 concat函数能够完成一些没有重叠索引的数据

首先对Series:



s1=pd.Series([1,2],index=['a','b'])
s2=pd.Series([5,6,4],index=['c','d','e'])
pd.concat([s1,s2])
返回
a    1
b    2
c    5
d    6
e    4
当指定axis=1时,会返回DataFrame

同时还可以指定在其他轴上边使用索引
pd.concat([s1,s2],axis=1,join_axes=[['a','c','d','e']])
返回
    0    1
a    1.0    NaN
c    NaN    5.0
d    NaN    6.0
e    NaN    4.0



当我们需要在连接轴上创建一个层次化索引的时候,可以用keys参数完成



pd.concat([s1,s2],keys=['one','two'])
返回
one  a    1
     b    2
two  c    5
     d    6
     e    4



在DataFrame中,也有相似的用法:

4、合并重叠数据

在numpy中,我们用where来完成合并

在series和dataframe中,我们用combine_first来实现:

5、轴向旋转数据

在DataFrame中,可以用stack:将列旋转为行;unstack:将行旋转至列。



data=pd.DataFrame(np.arange(6).reshape((2,3)),
                  index=pd.Index(['A','B'],name='state'),
                  columns=pd.Index(['one','two','three'],name='number'))
data
返回
number    one    two    three
state            
A    0    1    2
B    3    4    5

data.stack()   #得到的是series类型,不再是dataframe
返回
state  number
A      one       0
       two       1
       three     2
B      one       3
       two       4
       three     5



同样的,可以将层次化索引的series通过unstack重排为dataframe

而且,unstack在分组里面找不到值的时候,可能会引入缺失数据,

           stack默认会过滤掉缺失数据

6、数据转换 (过滤、清理)

 ①清除重复数据

在dataframe中,duplicated函数能够返回一个布尔型series,来表示是否有重复行;

                         而drop_duplicates函数则能够返回一个移除重复行的dataframe;



data = pd.DataFrame({'a1':['one']*3+['two']*4,
                    'a2':[1,2,2,3,3,4,4]})
data.duplicated()                
返回
0    False
1    False
2     True
3    False
4     True
5    False
6     True
data.drop_duplicates
返回
    a1    a2
0    one    1
1    one    2
3    two    3
5    two    4



.drop_duplicates(['a1'])   表示根据a1列过滤重复项

当我们想要保留重复项出现的后一个,则需要 指定keep=‘last’



data.drop_duplicates(['a1','a2'],keep='last')
返回
    a1    a2
0    one    1
2    one    2
4    two    3
6    two    4



②、通过函数或映射完成数据转换(map函数,修改对象的数据子集)

例如,给一个dataframe通过映射添加一列:



data=pd.DataFrame({'food':['bacon','pulled pork','bacon','Pastrami',
                           'corned beef','Bacon','pastrami','honey ham','nova lox'],
                  'ounces':[3,4,6,7,5,10,5,9,12]})

#映射为食物的来源动物
meat_to_animal={'bacon':'pig','pulled pork':'pig','pastrami':'cow',
               'corned beef':'cow','honey ham':'pig','nova lox':'salmon'}

data['animal'] = data['food'].map(str.lower).map(meat_to_animal)#肉类的首字母大小写不统一,转换一下
data
返回
      food      ounces  animal
0    bacon          3    pig
1    pulled pork    4    pig
2    bacon          6    pig
3    Pastrami       7    cow
4    corned beef    5    cow
5    Bacon         10    pig
6    pastrami       5    cow
7    honey ham      9    pig
8    nova lox      12    salmon



或者通过一个匿名函数完成:注:原dataframe并未发生改变



data['food'].map(lambda x: meat_to_animal[x.lower()])
返回
0       pig
1       pig
2       pig
3       cow
4       cow
5       pig
6       cow
7       pig
8    salmon
Name: food, dtype: object



③、替换值(replace函数)

fillna其实是填充缺失数据的一种特殊情况:



data = pd.Series([1,-999,2,-999,-1000,3])
-999可能是表示缺失数据的标记值,我们需要替换成pandas可以接受的NA值
data.replace(-999,np.nan)
返回
0       1.0
1       NaN
2       2.0
3       NaN
4   -1000.0
5       3.0

一次性替换多个值时:
data.replace([-999,-1000],np.nan)
返回
0    1.0
1    NaN
2    2.0
3    NaN
4    NaN
5    3.0

一一对应替换
data.replace([-999,-1000],[np.nan,0])   #传入参数也可以是字典
返回
0    1.0
1    NaN
2    2.0
3    NaN
4    0.0
5    3.0



④、重命名轴索引

用到的函数:rename,复制DataFrame并对索引和列标签进行赋值



我们来创建一个数据集的转换版
data = pd.DataFrame(np.arange(12).reshape((3,4)),
                    index = ['Ohio','Colorado','New York'],
                    columns = ['one','two','three','four'])
data.rename(index = str.title,columns = str.upper)
返回

           ONE  TWO THREE FOUR
Ohio        0    1    2    3
Colorado    4    5    6    7
New York    8    9    10    11
另外,rename也可以结合自典型对象实现轴标签更新:
data.rename(index = {'Ohio':'Indiana'},
           columns = {'THREE':'peekaboo'})
返回
         one    two    three    four
Indiana    0    1    2    3
Colorado    4    5    6    7
New York    8    9    10    11



⑤、离散化和面元(bin)划分

在pandas中我们用cut来数据的划分:



ages = [19,30,28,60,38,45,20,25,71,37,29,54]
bins =[18,25,35,60,100]
cuts = pd.cut(ages,bins)
cuts
返回
[(18, 25], (25, 35], (25, 35], (35, 60], (35, 60], ..., (18, 25], (60, 100], (35, 60], (25, 35], (35, 60]]
Length: 12
Categories (4, interval[int64]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]
当然也可以通过计数得出每个区间个数
pd.value_counts(cuts)
返回
(35, 60]     5
(25, 35]     3
(18, 25]     3
(60, 100]    1



当right=True时,表示左开右闭,当right=False时,表示左闭右开



pd.cut(ages,[18,26,36,61,100],right=False)
返回
[[18, 26), [26, 36), [26, 36), [36, 61), [36, 61), ..., [18, 26), [61, 100), [36, 61), [26, 36), [36, 61)]
Length: 12
Categories (4, interval[int64]): [[18, 26) < [26, 36) < [36, 61) < [61, 100)]



也可以自定义面元名称:



group_names = ['Youth','YoungAdult','MiddleAged','Senior']
pd.cut(ages,bins,labels = group_names)
返回
[Youth, YoungAdult, YoungAdult, MiddleAged, MiddleAged, ..., Youth, Senior, MiddleAged, YoungAdult, MiddleAged]
Length: 12
Categories (4, object): [Youth < YoungAdult < MiddleAged < Senior]



当我们向cut传入了面元的数量,而不是面元边界,会自动通过最大最小值计算等长bin

qcut能够根据样本分位数对数据进行bin划分



data = np.random.randn(1000)
cuts = pd.qcut(data,4)
cuts
返回
[(0.664, 3.276], (0.664, 3.276], (-0.62, 0.031], (-3.3729999999999998, -0.62], (0.664, 3.276], ..., (0.664, 3.276], (0.664, 3.276], (0.664, 3.276], (-3.3729999999999998, -0.62], (-0.62, 0.031]]
Length: 1000
Categories (4, interval[float64]): [(-3.3729999999999998, -0.62] < (-0.62, 0.031] < (0.031, 0.664] < (0.664, 3.276]]

计数
pd.value_counts(cuts)
返回
(0.664, 3.276]                  250
(0.031, 0.664]                  250
(-0.62, 0.031]                  250
(-3.3729999999999998, -0.62]    250



qcut还可以自定义分位数(0-1之间,两边都闭):



pd.qcut(data,[0,0.1,0.5,0.9,1])
返回
[(0.031, 1.216], (1.216, 3.276], (-1.193, 0.031], (-3.3729999999999998, -1.193], (0.031, 1.216], ..., (0.031, 1.216], (1.216, 3.276], (0.031, 1.216], (-3.3729999999999998, -1.193], (-1.193, 0.031]]
Length: 1000
Categories (4, interval[float64]): [(-3.3729999999999998, -1.193] < (-1.193, 0.031] < (0.031, 1.216] < (1.216, 3.276]]



⑥、检测和过滤异常值;

 我们随机生成一组正态分布的数据,并对数据进行操作,假设绝对值大于3的数据都属于异常值,处理结果如下:



data = pd.DataFrame(np.random.randn(1000,4))
data.describe()
返回  
              0              1             2               3
count    1000.000000    1000.000000    1000.000000    1000.000000
mean    0.004248    -0.011778    -0.005787    -0.053237
std    0.976084    1.020196    1.029432    0.979127
min    -3.678284    -2.695522    -3.432793    -3.393575
25%    -0.681090    -0.663212    -0.745234    -0.693163
50%    0.007591    -0.003798    0.010426    -0.020312
75%    0.685027    0.646247    0.724293    0.610705
max    3.836988    3.666919    3.069855    3.051585

找出绝对值大于3的数据的所有行
data[(np.abs(data)>3).any(1)]
返回
           0           1            2          3
19    -0.013692    3.279487    -0.055036    -1.515724
52    -0.827221    3.666919    -0.302976    -0.693555
114    0.611680    3.106616    -0.084244    0.682607
123    -0.621681    0.801968    -3.001182    -0.843664
133    3.836988    1.765709    3.069855    0.320651
156    0.434825    0.525397    -0.572917    -3.149598
205    -0.415999    3.185963    -0.762609    0.543016
270    -3.678284    -1.313117    0.053046    -0.670639
423    1.847537    -1.540281    -0.163496    -3.393575
505    -3.012297    -0.497900    1.715688    -1.504392
657    1.885955    3.158016    -0.972898    -1.143324
692    0.360870    0.347168    -0.460957    -3.329502
704    0.565049    1.061580    -3.059464    0.064454
760    -0.285920    -0.448922    -3.432793    -1.888091
902    -1.453302    1.406283    -0.333558    3.051585
我们可以限制数据在-3<数据<3
datas = np.sign(data)*3
data.describe()
返回
              0              1             2             3
count    1000.000000    1000.000000    1000.000000    1000.000000
mean    0.004101    -0.013175    -0.005364    -0.052415
std    0.970775    1.015766    1.027695    0.976185
min    -3.000000    -2.695522    -3.000000    -3.000000
25%    -0.681090    -0.663212    -0.745234    -0.693163
50%    0.007591    -0.003798    0.010426    -0.020312
75%    0.685027    0.646247    0.724293    0.610705
max    3.000000    3.000000    3.000000    3.000000



np.sign()返回一个由-1和1组成的数组,用来表示原始值的符号

⑦、排列和随机采样

对DataFrame和Series的列实现随机重排序,用到np.random.permutation函数



df = pd.DataFrame(np.arange(6*4).reshape(6,4))
samper = np.random.permutation(6)
samper
返回
array([4, 1, 3, 5, 0, 2])
利用take函数使用该数组,得到
df.take(samper)
    0    1    2    3
4    16    17    18    19
1    4    5    6    7
3    12    13    14    15
5    20    21    22    23
0    0    1    2    3
2    8    9    10    11
当然,也可以通过permutation随机选取子集:
df.take(np.random.permutation(len(df))[:3])
返回

     0    1    2    3
0    0    1    2    3
4    16    17    18    19
3    12    13    14    15



  当通过替换的方式产生样本时,可以通过np.random.randint:

 

get_dummies函数,产生一个k列矩阵或dataframe,其中k的意思是:一个dataframe中某一列有k个不同的值:

结合get_dummies和类似于cut等的离散化函数,能够很好完成统计应用:



values = np.random.rand(10)
bins = [0,0.2,0.4,0.6,0.8,1]
pd.get_dummies(pd.cut(values,bins))
返回
    (0.0, 0.2]    (0.2, 0.4]    (0.4, 0.6]    (0.6, 0.8]    (0.8, 1.0]
0    0    0    0    1    0
1    0    0    0    0    1
2    0    0    1    0    0
3    0    0    0    1    0
4    0    1    0    0    0
5    0    1    0    0    0
6    1    0    0    0    0
7    0    0    1    0    0
8    1    0    0    0    0
9    0    0    0    0    1



7、字符串的相关操作

对字符串的操作主要有:

拆分-----split,指定分隔符

修剪空白符---strip

小写----lower

大写---upper

正则表达式(一种在文本中搜索匹配字符串模式的方法)

   python里面的re模块负责对字符串应用正则表达式

import re
re.match #从开始位置开始匹配,只返回字符串的首部

re.search #搜索整个字符串,返回第一个匹配项

re.findall #搜索整个字符串,返回一个list,字符串的所有匹配项
常用功能函数:

   


https://www.xamrdz.com/lan/5cc1959816.html

相关文章: