数据整理

采集到的原始数据往往有各种各样的问题,如取自不同源的数据格式不统一、格式不规范、名称不统一、数据错误等。所以,进行正式的统计分析之前需要先对数据进行整理。MATLAB的表和Python的DataFrame封装了大量进行数据整理的函数和方法,本节主要介绍它们的使用。[大谦MATLAB,dqmatlab点com]

列索引

列操作是数据整理中最常见的操作,包括列的增、删、改、查等操作。列索引指的是列的查找。可以有单个列的索引、多个不连续列的索引和多个连续列的索引(即切片)。

首先介绍单个列的索引。

【MATLAB】

下面首先创建一个表T。

code.matlab
>> ID={'1';'2';'3';'4'};
>> Name={'张三';'李四';'杨二';'王五'};
>> Age=[18;19;17;21];
>> Height=[162;169;164;167];
>> Weight=[116;103;131;133];
>> T=table(Name,Age,Height,Weight, 'RowNames',ID);

用小括号获取表T中的第1列。注意小括号中有两个参数,第1个参数取冒号,表示包括所有行;第2个参数取1,表示第1列。

code.matlab
>> T1=T(:,1)
T1 =
  4×1 table
           Name
         ________
    1    {'张三'}
    2    {'李四'}
    3    {'杨二'}
    4    {'王五'}

返回的是一个4行1列的子表。

也可以用第1列的名称进行索引,即

code.matlab
>> T2=T(:,'Name')

返回与上面相同的结果。

【Python】

下面创建一个DataFrame对象df。

code.python
>>> import pandas as pd
>>> df=pd.DataFrame([['1','张三',18,162,116],['2','李四',19,169,103],['3','杨二',17,164,131],['4','王五',25,167,133]],columns=['ID','Name','Age','Height','Weight'])
>>> df.set_index('ID',inplace=True)

用中括号获取列索引标签为" A"的列。

code.python
>>> df['Name']
0    张三
1    李四
2    杨二
3    王五
Name: Name, dtype: object

查看数据类型。

code.python
>>> type(df['Name'])
<class 'pandas.core.series.Series'>

可见,通过索引获取DataFrame数据的单列时得到的是一个Series类型的数据。

上面用中括号获取列,用loc方法也可以获取列,例如:

code.python
>>> df.loc[:,'Age']
0    18
1    19
2    17
3    25
Name: Age, dtype: int64

中括号中的冒号表示Age标签对应的各行数据全部取。

用中括号获取列时中括号里面输入的是单列的标签,此时返回的是Series类型的数据。

用中括号索引列以后,引用values属性得到的是NumPy数组数据。

code.python
>>> v=df['Age'].values
>>> v
array([18, 19, 17, 25], dtype=int64)
>>> type(v)
<class 'numpy.ndarray'>

对给定表的不连续多列进行索引,用普通数组指定不连续多列的编号。

【MATLAB】

下面获取表T中的第2列和第4列,把列号2和4放在一个数组中作为小括号中的第2个参数。

code.matlab
>> T3= T(:,[2 4])
T3 =
  4×2 table
         Age    Weight
         ___    ______
    1    18      116
    2    19      103
    3    17      131
    4    21      133

返回一个包含表T中第2列和第4列的子表。

也可以使用元胞数组,用不连续列的名称进行索引。下面用名称索引实现对表T中的第2列和第4列的索引。

code.matlab
>> T4=T(:,{'Age','Weight'})

返回与T3相同的子表。

【Python】

可以通过指定多个索引标签来获取多个列。这多个列的索引标签组成列表放在中括号中。

code.python
>>> c24=df[['Age','Weight']]
>>> c24
   Age  Weight
0   18     116
1   19     103
2   17     131
3   25     133

查看c24的数据类型。

code.python
>>> type(c24)
<class 'pandas.core.frame.DataFrame'>

可见,获取多列返回的是DataFrame类型的数据。

对表中的连续多列进行索引,使用类似m:n的形式指定连续多列,其中m和n分别为起始列号和终止列号。

【MATLAB】

下面对表T中的第1-3列进行索引。起始列号为1,终止列号为3,1和3之间用冒号连接。

code.matlab
>> T5= T(:,1:3)
T5 =
  4×3 table
           Name      Age    Height
         ________    ___    ______
    1    {'张三'}    18      162
    2    {'李四'}    19      169
    3    {'杨二'}    17      164
    4    {'王五'}    21      167

返回一个包含表T中第1-3列的子表。

【Python】

使用冒号可以对DataFrame数据进行切片。下面的切片取所有行,取列标签"Name"到"Height"的所有列。

code.python
>>> df.loc[:,'Name':'Height']
  Name  Age  Height
0   张三   18     162
1   李四   19     169
2   杨二   17     164
3   王五   25     167

取“Age”及其之后的所有列。

code.python
>>> df.loc[:,'Age':]
   Age  Height  Weight
0   18     162     116
1   19     169     103
2   17     164     131
3   25     167     133

添加列和插入列

可以在表和DataFrame的末尾添加新的列,或者在指定位置插入新的列。

【MATLAB】

下面创建新的表T。

code.matlab
>> ID={'1';'2';'3';'4'};
>> Name={'张三';'李四';'杨二';'王五'};
>> Age=[18;19;17;21];
>> Height=[162;169;164;167];
>> Weight=[116;103;131;133];
>> T=table(Name,Age,Height,Weight, 'RowNames',ID);

使用点引用的方式在表后面添加“Married”列。

code.matlab
>> T.Married=[0;0;0;1]
T =
  4×5 table
           Name      Age    Height    Weight    Married
         ________    ___    ______    ______    _______
    1    {'张三'}    18      162       116         0
    2    {'李四'}    19      169       103         0
    3    {'杨二'}    17      164       131         0
    4    {'王五'}    21      167       133         1

【Python】

下面创建新的DataFrame df。

code.python
>>> import pandas as pd
>>> df=pd.DataFrame([['1','张三',18,162,116],['2','李四',19,169,103],['3','杨二',17,164,131],['4','王五',25,167,133]],columns=['ID','Name','Age','Height','Weight'])
>>> df.set_index('ID',inplace=True)

在df的最后添加新列“Married”。

code.python
>>> df['Married']=[0,0,0,1]
>>> df
   Name  Age  Height  Weight  Married
ID
1    张三   18     162     116        0
2    李四   19     169     103        0
3    杨二   17     164     131        0
4    王五   25     167     133        1

可以在指定位置插入列。

【MATLAB】

下面使用addvars函数在表T中“Age”列的前面插入新列“Gender”。

code.matlab
>> Gender={'M';'M';'M';'M'};
>> T2=addvars(T,Gender,'Before','Age')
T2 =
  4×6 table
           Name      Gender    Age    Height    Weight    Married
         ________    ______    ___    ______    ______    _______
    1    {'张三'}    {'M'}     18      162       116         0
    2    {'李四'}    {'M'}     19      169       103         0
    3    {'杨二'}    {'M'}     17      164       131         0
    4    {'王五'}    {'M'}     21      167       133         1

【Python】

下面使用DataFrame对象的insert方法在DataFrame df中“Age”列的前面插入新列“Gender”。

code.python
>>> df.insert(loc=1,column='Gender',value=['M','M','M','M'])
>>> df
   Name Gender  Age  Height  Weight  Married
ID
1    张三      M   18     162     116        0
2    李四      M   19     169     103        0
3    杨二      M   17     164     131        0
4    王五      M   25     167     133        1

已有列数据转换得到新列

常见的一种列操作是在已有列数据的基础上进行简单计算、进行转换或统计得到新的列。例如某列的数据都乘以2得到新列,或求各列的和得到新列的汇总数据等。

【MATLAB】

下面创建一个简单的表,有A,B两列。

code.matlab
>> A=table([1;2;3;4],[5;6;7;8],'VariableNames',{'A' 'B'})
>> A =
  4×2 table
    A    B
    _    _
    1    5
    2    6
    3    7
    4    8

添加C列,C列的值等于A列的值乘以B列的值。

code.matlab
>> A.C=A.A.*A.B
A =
  4×3 table
    A    B    C
    _    _    __
    1    5     5
    2    6    12
    3    7    21
    4    8    32

【Python】

创建简单的DataFrame,有A和B两列。

code.python
>>> import pandas as pd
>>> df=pd.DataFrame([[1,5],[2,6],[3,7],[4,8]],columns=['A','B'])
>>> df
   A  B
2  1  5
3  2  6
2  3  7
3  4  8

给DataFrame添加新列C,新列的值为A列的值乘以B列的值。

code.python
>>> df['C']=df['A']*df['B']
>>> df
   A  B   C
0  1  5   5
1  2  6  12
2  3  7  21
3  4  8  32

Python中还可以用Series对象的apply方法、map方法、transform方法和assign方法等结合匿名函数和自定义函数通过计算得到新列。

下面用Series对象的apply方法结合匿名函数添加D列,D列的值等于A列的值乘以1.2。

code.python
>>> df['D']=df['A'].apply(lambda x:x*1.2)    #转换

下面用Series对象的apply方法结合自定义函数添加E列,E列的值等于B列的值乘以1.2。

code.python
>>> def new_v(x):
       return(x*1.2)
>>> df['E']=df['B'].apply(new_v)

下面用Series对象的map方法结合匿名函数添加F列,F列的值等于C列的值乘以1.2。

code.python
>>> df['F']=df['C'].map(lambda x:x*1.2)    #转换
>>> df['G']=df['C'].map(new_v)

下面用Series对象的transform方法结合匿名函数添加H列,H列的值等于A列的值乘以1.2。

code.python
>>> df['H']=df['A'].transform(lambda x:x*1.2)    #转换

下面用DataFrame对象的assign方法添加J列,J列的值等于A列的值乘以1.2。

code.python
>>> df=df.assign(J=df['A']*1.2)

下面用DataFrame对象的assign方法结合匿名函数添加K列,K列的值等于A列的值乘以1.2。

code.python
>>> df=df.assign(K=lambda x:x.A*1.2)

下面用DataFrame对象的apply方法结合NumPy包的求和函数sum添加“Total”列,该列的值等于A列、B列值的和。

code.python
>>> df['Total']=df.apply(np.sum,axis=1)   #行求和,综述统计量

下面用DataFrame对象的agg方法结合sum函数添加“Total”列,该列的值等于A列、B列值的和。

code.python
>>> df['Total']=df.agg('sum',axis=1)    #综述统计量

修改列名

修改列名包括修改单个列的列名、修改多个列的列名和修改全部列的列名几种情况。

【MATLAB】

下面创建一个表T。

code.matlab
>> T=table({'张三';'李四';'杨二';'王五'},{'M';'F';'M';'F'},[18;19;17;25],...
    [162;169;164;167],...
    'VariableNames',{'Name' 'Gender' 'Age' 'Height'})
T =
  4×4 table
      Name      Gender    Age    Height
    ________    ______    ___    ______
    {'张三'}    {'M'}     18      162
    {'李四'}    {'F'}     19      169
    {'杨二'}    {'M'}     17      164
    {'王五'}    {'F'}     25      167

用Properties.VariableNames属性将表T中Gender列的列名改为“Sex”。

code.matlab
>> T.Properties.VariableNames{'Gender'}='Sex'
T =
  4×4 table
      Name       Sex     Age    Height
    ________    _____    ___    ______
    {'张三'}    {'M'}    18      162
    {'李四'}    {'F'}    19      169
    {'杨二'}    {'M'}    17      164
    {'王五'}    {'F'}    25      167

【Python】

下面创建一个DataFrame df。

code.python
>>> import pandas as pd
>>> df=pd.DataFrame([['张三','M',18,162],['李四','M',19,169],['杨二','M',17,164],['王五','M',25,167]],columns=['Name','Gender','Age','Height'])
>>> df
  Name Gender  Age  Height
0   张三      M   18     162
1   李四      M   19     169
2   杨二      M   17     164
3   王五      M   25     167

用DataFrame对象的rename方法将Gender列的列名改为“Sex”。

code.python
>>> df.rename(columns={'Gender':'Sex'}, inplace=True)
>>> df
  Name Sex  Age  Height
0   张三   M   18     162
1   李四   M   19     169
2   杨二   M   17     164
3   王五   M   25     167

【MATLAB】

下面创建表T,并用renamevars函数将表中Gender列和Age列的列名改为“Sex”和“Years Old”。注意,修改前的列名和修改后的列名分别放在两个数组中作为renamevars函数的参数。

code.matlab
>> T=table({'张三';'李四';'杨二';'王五'},{'M';'F';'M';'F'},[18;19;17;25],...
    [162;169;164;167],...
    'VariableNames',{'Name' 'Gender' 'Age' 'Height'});
>> T=renamevars(T,["Gender","Age"],["Sex","Years Old"])
T =
  4×4 table
      Name       Sex     Years Old    Height
    ________    _____    _________    ______
    {'张三'}    {'M'}       18         162
    {'李四'}    {'F'}       19         169
    {'杨二'}    {'M'}       17         164
    {'王五'}    {'F'}       25         167

【Python】

下面创建DataFrame df,并用DataFrame对象的rename方法将DataFrame中Gender列和Age列的列名改为“Sex”和“Years Old”。注意,修改前的列名和修改后的列名分别组合成键值对,最后得到一个字典作为columns参数的值。

code.python
>>> import pandas as pd
>>> df=pd.DataFrame([['张三','M',18,162],['李四','M',19,169],['杨二','M',17,164],['王五','M',25,167]],columns=['Name','Gender','Age','Height'])
>>> df.rename(columns={'Gender':'Sex','Age':'Years Old'}, inplace=True)
>>> df
  Name Sex  Years Old  Height
0   张三   M         18     162
1   李四   M         19     169
2   杨二   M         17     164
3   王五   M         25     167

【MATLAB】

如果需要给所有列名添加前缀或后缀,在MATLAB中可以用上面修改多个列名的方法逐个修改。

【Python】

Python中可以使用DataFrame对象的add_prefix方法给列名添加前缀,用add_suffix方法给列名添加后缀。例如,下面给列名添加前缀“pf_”,添加后缀“_sf”。

code.python
>>> df=df.add_prefix('pf_')
>>> df=df.add_suffix('_sf')

下面用DataFrame对象的rename方法结合匿名函数给所有列名添加前缀“pf_”。

code.python
>>> df.rename(columns=lambda x:'pf_'+x,inplace=True)

修改列的数据类型

表或DataFrame中每列数据具有相同的数据类型。MATLAB和Python都提供了相应的函数或方法修改指定列的数据类型。

【MATLAB】

下面创建一个表T。

code.matlab
>> T=table({'张三';'李四';'杨二';'王五'},{'M';'F';'M';'F'},[18;19;17;25],...
    [162;169;164;167],...
    'VariableNames',{'Name' 'Gender' 'Age' 'Height'});

用summary函数查看每列的数据类型。

code.matlab
>> summary(T)
Variables:
    Name: 4×1 cell array of character vectors
    Gender: 4×1 cell array of character vectors
    …….

现在Gender列为字符向量组成的元胞数组。

用convertvars函数将Gender列的数据类型修改为分类数组,然后用summary函数查看修改后的表T2各列的数据类型。

code.matlab
>> T2=convertvars(T,{'Gender'},'categorical')
>> summary(T2)
Variables:
    Name: 4×1 cell array of character vectors
    Gender: 4×1 categorical
    ……

现在Gender列的数据类型变成了分类数组。

【Python】

下面先创建一个DataFrame df。

code.python
>>> import pandas as pd
>>> df=pd.DataFrame([['张三','M',18,162],['李四','M',19,169],['杨二','M',17,164],['王五','M',25,167]],columns=['Name','Gender','Age','Height'])

用DataFrame对象的dtypes属性查看各列的数据类型。

code.python
>>> df.dtypes
Name      object
Gender    object
Age        int64
Height     int64
dtype: object

现在Gender列是object类型。

用Series对象的astype方法将Gender列数据转换为分类数组,然后用dtypes属性查看修改后各列的数据类型。

code.python
>>> df['Gender']=df['Gender'].astype('category')
>>> df.dtypes
Name        object
Gender    category
Age          int64
Height       int64
dtype: object

现在Gender列的数据类型变成了分类数组。

修改列的数据

10.4.2小节介绍了通过对原有列数据进行数据转换可以创建新列,如果不创建新列,而是将转换后的数据代替原有列数据,就成了修改列数据。

【MATLAB】

下面创建一个表T。

code.matlab
>> T=table([1;2;3;4],[5;6;7;8],'VariableNames',{'A' 'B'})
>> T =
  4×2 table
    A    B
    _    _
    1    5
    2    6
    3    7
    4    8

修改A列的数据为原来数据的2倍。

code.matlab
>> T.A=T.A.*2
T =
  4×2 table
    A    B
    _    _
    2    5
    4    6
    6    7
    8    8

【Python】

下面创建DataFrame df。

code.python
>>> import pandas as pd
>>> df=pd.DataFrame([[1,5],[2,6],[3,7],[4,8]],columns=['A','B'])
>>> df
   A  B
0  1  5
1  2  6
2  3  7
3  4  8

修改A列数据为原来数据的2倍。

code.python
>>> df['A']=df['A']*2
>>> df
   A  B
0  2  5
1  4  6
2  6  7
3  8  8

也可以用Series对象的update方法指定数据进行修改。

code.python
>>> df['A'].update(pd.Series([3,8,10,5]))    #全部
>>> df
    A  B
0   3  5
1   8  6
2  10  7
3   5  8

使用update方法可以只修改列中的部分数据,此时需要指定修改的值和对应的行索引。例如,下面将A列中第1行和第4行的值修改为5和8。

code.python
>>> df['A'].update(pd.Series([5,8],index=[0,3]))    #部分
>>> df
    A  B
0   5  5
1   8  6
2  10  7
3   8  8

使用DataFrame对象的update方法可以用一个DataFrame A的数据更新另一个DataFrame B的数据,但是只更新B中与A相交的部分。下面创建两个DataFrame df1和df2。

code.python
>>> df1=pd.DataFrame({'A':[1,2,3],'B':[20,30,40]})
>>> df1
   A   B
0  1  20
1  2  30
2  3  40
>>> df2=pd.DataFrame({'B':[4,5,6],'C':[8,9,10]})
>>> df2
   B   C
0  4   8
1  5   9
2  6  10

用df2更新df1,df1中与df2相交的B列数据被更新。

code.python
>>> df1.update(df2)
>>> df1
   A  B
0  1  4
1  2  5
2  3  6

删除列

使用MATLAB和Python提供的函数或方法删除表或DataFrame中的列。

【MATLAB】

下面创建表T,使用removevars函数从表中删除Height列。

code.matlab
>> T=table({'张三';'李四';'杨二';'王五'},{'M';'F';'M';'F'},[18;19;17;25],...
    [162;169;164;167],...
    'VariableNames',{'Name' 'Gender' 'Age' 'Height'});
>> removevars(T,{'Height'})
ans =
  4×3 table
      Name      Gender    Age
    ________    ______    ___
    {'张三'}    {'M'}     18
    {'李四'}    {'F'}     19
    {'杨二'}    {'M'}     17
    {'王五'}    {'F'}     25

还可以通过点引用列,并将该列的值设置为空矩阵来删除列。下面从表T中删除Age列。

code.matlab
>> T.Age=[];
>> T
T =
  4×3 table
      Name      Gender    Height
    ________    ______    ______
    {'张三'}    {'M'}      162
    {'李四'}    {'F'}      169
    {'杨二'}    {'M'}      164
    {'王五'}    {'F'}      167

【Python】

下面创建DataFrame df,使用DataFrame对象的drop方法删除Height列。

code.python
>>> import pandas as pd
>>> df=pd.DataFrame([['张三','M',18,162],['李四','M',19,169],['杨二','M',17,164],['王五','M',25,167]],columns=['Name','Gender','Age','Height'])
>>> df=df.drop('Height', axis=1)
>>> df
  Name Gender  Age
0   张三      M   18
1   李四      M   19
2   杨二      M   17
3   王五      M   25

行索引

前面介绍了表和DataFrame中的列操作,与之对应的有行操作,接下来介绍行的增、删、改、查。行索引是与行查找有关的操作,包括单个行的索引、不连续多个行的索引和连续多个行的索引(即切片)。

【MATLAB】

下面创建一个表T。

code.matlab
>> T=table({'张三';'李四';'杨二';'王五'},{'M';'F';'M';'F'},[18;19;17;25],...
    [162;169;164;167],...
    'VariableNames',{'Name' 'Gender' 'Age' 'Height'});

获取表T中的第1行。

code.matlab
>> T1=T(1,:)
T1 =
  1×4 table
      Name      Gender    Age    Height
    ________    ______    ___    ______
    {'张三'}    {'M'}     18      162

注意此时返回的是一个1行4列的子表。

也可以用第1行的名称进行索引,先给表T添加索引列。

code.matlab
>> T.Properties.RowNames={'1';'2';'3';'4'}
T =
  4×4 table
           Name      Gender    Age    Height
         ________    ______    ___    ______
    1    {'张三'}    {'M'}     18      162
    2    {'李四'}    {'F'}     19      169
    3    {'杨二'}    {'M'}     17      164
    4    {'王五'}    {'F'}     25      167

获取行名为“1”的行。

code.matlab
>> T2=T({'1'},:)
T2 =
  1×4 table
           Name      Gender    Age    Height
         ________    ______    ___    ______
    1    {'张三'}    {'M'}     18      162

【Python】

Python中使用中括号获取单个行。下面创建一个DataFrame对象df。

code.python
>>> df=pd.DataFrame([['1','张三',18,162,116],['2','李四',19,169,103],['3','杨二',17,164,131],['4','王五',25,167,133]],columns=['ID','Name','Age','Height','Weight'])
>>> df.set_index('ID',inplace=True)

用DataFrame对象的loc方法获取行名为“1”的行r1。

code.python
>>> r1=df.loc['1']
>>> r1
Name       张三
Age        18
Height    162
Weight    116
Name: 1, dtype: object

查看r1的数据类型。

code.python
>>> type(r1)
<class 'pandas.core.series.Series'>

可见,通过索引获取DataFrame数据的单行时得到的是一个Series类型的数据。也可以用iloc方法获取行,与loc方法不同的是,iloc方法的参数为表示行编号的整数,不是标签。

对给定表的不连续多行进行索引,用普通数组指定不连续多行的编号。

【MATLAB】

下面获取表T中的第1行、第3行和第5行。

code.matlab
>> T3=T([1 3],:)
T3 =
  2×4 table
           Name      Gender    Age    Height
         ________    ______    ___    ______
    1    {'张三'}    {'M'}     18      162
    3    {'杨二'}    {'M'}     17      164

返回一个包含表T中第1行和第3行的子表。

也可以使用元胞数组,用不连续行的名称进行索引。下面用名称索引实现对表T中的第1行和第3行的索引。

code.matlab
>> T.Properties.RowNames={'1';'2';'3';'4'};
>> T4=T({'1','3'},:)
T4 =
  2×4 table
           Name      Gender    Age    Height
         ________    ______    ___    ______
    1    {'张三'}    {'M'}     18      162
    3    {'杨二'}    {'M'}     17      164

【Python】

可以通过指定多个索引标签来获取多个行。这多个行的索引标签组成列表放在中括号中。下面获取df中行名为“1”和“3”的行。

code.python
>>> r13=df.loc[['1','3']]
>>> r13
   Name  Age  Height  Weight
ID
1    张三   18     162     116
3    杨二   17     164     131

查看r13的数据类型。

code.matlab
>>> type(r13)
<class 'pandas.core.frame.DataFrame'>

可见,获取多行返回的是DataFrame类型的数据。

对表中的连续多行进行索引,使用类似m:n的形式指定连续多行,其中m和n分别为起始行号和终止行号。

【MATLAB】

下面对表T中的第1-3行进行索引。小括号中的冒号表示取所有列。

code.matlab
>> T5=T(1:3,:)
T5 =
  3×4 table
           Name      Gender    Age    Height
         ________    ______    ___    ______
    1    {'张三'}    {'M'}     18      162
    2    {'李四'}    {'F'}     19      169
    3    {'杨二'}    {'M'}     17      164

返回一个包含表T中第1-3行的子表。

【Python】

下面的切片取行名"1"到"3"的所有行。

code.python
>>> df.loc['1':'3',:]
   Name  Age  Height  Weight
ID
1    张三   18     162     116
2    李四   19     169     103
3    杨二   17     164     131

下面的切片取行名"2"及后面的所有行。

code.python
>>> df.loc['2':,:]
   Name  Age  Height  Weight
ID
2    李四   19     169     103
3    杨二   17     164     131
4    王五   25     167     133

直接添加行

可以像直接添加列一样向表或DataFrame添加新行。

【MATLAB】

下面创建一个表T。

code.matlab
>> T=table({'张三';'李四';'杨二';'王五'},[18;19;17;25],...
    [162;169;164;167], [116;103;131;133],'VariableNames',...
{'Name' 'Age' 'Height' 'Weight'})
T =
  4×4 table
      Name      Age    Height    Weight
    ________    ___    ______    ______
    {'张三'}    18      162       116
    {'李四'}    19      169       103
    {'杨二'}    17      164       131
    {'王五'}    25      167       133

向表T追加一个新行。直接对新行进行索引赋值即可。

code.matlab
>> T(5,:)={'韩英',19,173,93}
T =
  5×4 table
      Name      Age    Height    Weight
    ________    ___    ______    ______
    {'张三'}    18      162       116
    {'李四'}    19      169       103
    {'杨二'}    17      164       131
    {'王五'}    25      167       133
    {'韩英'}    19      173        93

【Python】

创建一个新的DataFrame df。

code.python
>>> df=pd.DataFrame([['1','张三',18,162,116],['2','李四',19,169,103],['3','杨二',17,164,131],['4','王五',25,167,133]],columns=['ID','Name','Age','Height','Weight'])
>>> df.set_index('ID',inplace=True)

向df追加一个新行。直接对新行进行索引赋值即可。

code.python
>>> df.loc['5',:]=['韩英',19,173,93]
>>> df
   Name   Age  Height  Weight
ID
1    张三  18.0   162.0   116.0
2    李四  19.0   169.0   103.0
3    杨二  17.0   164.0   131.0
4    王五  25.0   167.0   133.0
5    韩英  19.0   173.0    93.0

已有行数据转换得到新行

此操作跟列的处理类似,利用已有的行数据进行转换得到新的行。

【MATLAB】

下面创建一个新表T。

code.matlab
>> T=table([1;2;3;4],[5;6;7;8],'VariableNames',{'A' 'B'});
>> T.Properties.RowNames={'a';'b';'c';'d'}
>> T =
  4×2 table
         A    B
         _    _
    a    1    5
    b    2    6
    c    3    7
    d    4    8

向T追加行名为“e”的新行,行数据利用行名为“a”的行的值乘以2。

code.matlab
>> T('e',:)=T('a',:).*2
T =
  5×2 table
         A    B
         _    __
    a    1     5
    b    2     6
    c    3     7
    d    4     8
    e    2    10

【Python】

下面创建新的DataFrame df。

code.python
>>> import pandas as pd
>>> df=pd.DataFrame([[1,5],[2,6],[3,7],[4,8]],index=['a','b','c','d'],columns=['A','B'])
>>> df
   A  B
a  1  5
b  2  6
c  3  7
d  4  8

向df追加行名为“e”的新行,行数据利用行名为“a”的行的值乘以2。

code.python
>>> df.loc['e']=df.loc['a']*2
>>> df
     A     B
a  1.0   5.0
b  2.0   6.0
c  3.0   7.0
d  4.0   8.0
e  2.0  10.0

下面使用DataFrame对象的apply方法和NumPy包的求和函数sum计算每列数据的和,并组成新的行“Total”。

code.python
>>> df.loc['Total']=df.apply(np.sum)
>>> df
          A     B
a       1.0   5.0
b       2.0   6.0
c       3.0   7.0
d       4.0   8.0
e       2.0  10.0
Total  12.0  36.0

下面使用DataFrame对象的agg方法和sum函数计算每列数据的和,并组成新的行“Total”。

code.python
>>> df.loc['Total']=df.agg('sum')   #列求和

更改行数据

更改行数据,直接索引到该行并重新赋值即可。

【MATLAB】

下面创建表T。

code.matlab
>> T=table([1;2;3;4],[5;6;7;8],'VariableNames',{'A' 'B'});
>> T.Properties.RowNames={'a';'b';'c';'d'};

将行名为“d”的行数据乘以2。

code.matlab
>> T('d',:)=T('d',:).*2
T =
  4×2 table
         A    B
         _    __
    a    1     5
    b    2     6
    c    3     7
    d    8    16

【Python】

下面创建DataFrame df。

code.python
>>> import pandas as pd
>>> df=pd.DataFrame([[1,5],[2,6],[3,7],[4,8]],index=['a','b','c','d'],columns=['A','B'])

将行名为“a”的行数据乘以2。

code.python
>>> df.loc['a']=df.loc['a']*2
>>> df
   A   B
a  2  10
b  2   6
c  3   7
d  4   8

下面给行名为“d”的行赋新值。

code.python
>>> df.loc['d']=[32,25]
>>> df
    A   B
a   2  10
b   2   6
c   3   7
d  32  25

删除行

删除表或DataFrame中的行,先索引到要删除的行,然后用MATLAB和Python提供的方法进行删除。

【MATLAB】

MATLAB中删除行,先索引到该行,然后给它赋空数组。下面创建表T,删除第1至3行。

code.matlab
>> T=table({'张三';'李四';'杨二';'王五'},[18;19;17;25],...
    [162;169;164;167], [116;103;131;133],'VariableNames',...
{'Name' 'Age' 'Height' 'Weight'});
>> T(1:3,:)=[];
>> T
T =
  1×4 table
      Name      Age    Height    Weight
    ________    ___    ______    ______
    {'王五'}    25      167       133

下面重新创建表T,删除第2和第4行。

code.python
>> T=table({'张三';'李四';'杨二';'王五'},[18;19;17;25],...
    [162;169;164;167], [116;103;131;133],'VariableNames',...
{'Name' 'Age' 'Height' 'Weight'});
>> T([2,4],:)=[];
>> T
T =
  2×4 table
      Name      Age    Height    Weight
    ________    ___    ______    ______
    {'张三'}    18      162       116
    {'杨二'}    17      164       131

【Python】

Python中用DataFrame对象的drop方法删除行。下面创建DataFrame df。

code.matlab
>>> df=pd.DataFrame([['1','张三',18,162,116],['2','李四',19,169,103],['3','杨二',17,164,131],['4','王五',25,167,133]],columns=['ID','Name','Age','Height','Weight'])

用DataFrame对象的drop方法删除第2行和第4行。

code.python
>>> df=df.drop([1,3])
>>> df
  ID Name  Age  Height  Weight
0  1   张三   18     162     116
2  3   杨二   17     164     131

重新创建DataFrame df,用行名删除第2行和第4行。

code.python
>>> df=pd.DataFrame([['1','张三',18,162,116],['2','李四',19,169,103],['3','杨二',17,164,131],['4','王五',25,167,133]],columns=['ID','Name','Age','Height','Weight'])
>>> df.set_index('ID',inplace=True)
>>> df=df.drop(['2','4'])
>>> df
   Name  Age  Height  Weight
ID
1    张三   18     162     116
3    杨二   17     164     131

值索引

对表或DataFrame中的值进行索引,需要指定该值所在的行号和列号,或者该值所对应的行名和列名。

【MATLAB】

下面创建表T,获取表中第1行第3列处的值。

code.matlab
>> T=table({'张三';'李四';'杨二';'王五'},[18;19;17;25],...
    [162;169;164;167], [116;103;131;133],'VariableNames',...
{'Name' 'Age' 'Height' 'Weight'});
>> A=T{1,3}
A =
   162

也可以用行和列的名称进行索引。

code.matlab
>> T.Properties.RowNames={'a';'b';'c';'d'};
>> A=T{'a','Height'}
A =
   162

下面获取第1行中第2列到第4列的值。

code.matlab
>> B=T{1,2:4}
B =
    18   162   116

下面获取第1列中第2行到第4行的值。

code.matlab
>> C=T{2:4,1}
C =
  3×1 cell 数组
    {'李四'}
    {'杨二'}
    {'王五'}

下面获取第1行到第3行、第2列到第4列的局部区域中的值。

code.matlab
>> D=T{1:3,2:4}
D =
    18   162   116
    19   169   103
    17   164   131

【Python】

下面创建DataFrame df,获取df中第1行第3列处的值。

code.python
>>> df=pd.DataFrame([['1','张三',18,162,116],['2','李四',19,169,103],['3','杨二',17,164,131],['4','王五',25,167,133]],columns=['ID','Name','Age','Height','Weight'])
>>> df.set_index('ID',inplace=True)
>>> a=df.iloc[0,2]
a =
   162

也可以用行和列的名称进行索引。

code.python
>>> a=df.loc['a','Height']
a =
   162

下面获取第1行中第2列到第4列的值。

code.python
>>> b=df.iloc[0,1:4]
>>> b
Age        18
Height    162
Weight    116
Name: 1, dtype: object

下面获取第1列中第2行到第4行的值。

code.python
>>> c=df.iloc[1:4,0]
>>> c
ID
2    李四
3    杨二
4    王五
Name: Name, dtype: object

下面获取第1行到第3行、第2列到第4列的局部区域中的值。

code.python
>>> d=df.iloc[0:3,1:4]
>>> d
    Age  Height  Weight
ID
1    18     162     116
2    19     169     103
3    17     164     131

修改单个值

修改单个值,只需要通过索引找到该值后重新赋值即可。

【MATLAB】

表中值的索引有值索引和元胞索引两种使用方式。下面创建一个表T。

code.matlab
>> T=table([1;2;3;4],[5;6;7;8],'VariableNames',{'A' 'B'});
>> T.Properties.RowNames={'a';'b';'c';'d'};

使用值索引方式将第3行第2列的值该为10。

code.matlab
>> T(3,2)={10}
T =
  4×2 table
         A    B
         _    __
    a    1     5
    b    2     6
    c    3    10
    d    4     8

使用值索引方式将行名为“d”,列名为“B”的值该为12。

code.matlab
>> T('d','B')={12}
T =
  4×2 table
         A    B
         _    __
    a    1     5
    b    2     6
    c    3    10
    d    4    12

使用元胞索引方式将第1行第2列的值该为20。

code.matlab
>> T{1,2}=20
T =
  4×2 table
         A    B
         _    __
    a    1    20
    b    2     6
    c    3    10
    d    4    12

使用元胞索引方式将行名为“d”,列名为“A”的值该为15。

code.matlab
>> T{'b','A'}=15
T =
  4×2 table
         A     B
         __    __
    a     1    20
    b    15     6
    c     3    10
    d     4    12

【Python】

Python中可以用DataFrame对象的iloc方法和loc方法索引值,并在索引后重新赋值来修改值。

下面创建一个DataFrame df。

code.python
>>> import pandas as pd
>>> df=pd.DataFrame([[1,5],[2,6],[3,7],[4,8]],index=['a','b','c','d'],columns=['A','B'])

修改第3行第2列处的值为10。

code.python
>>> df.iloc[2,1]=10
>>> df
   A   B
a  1   5
b  2   6
c  3  10
d  4   8

修改行号为“d”,列号为“B”处的值为12。

code.python
>>> df.loc['d','B']=12
>>> df
   A   B
a  1   5
b  2   6
c  3  10
d  4  12

修改不连续区域的值

对于不连续区域,需要用区域对应的行号和列号分别组成数组对表或DataFrame进行索引,然后用修改后的值组成二维数组进行赋值。

【MATLAB】

下面创建表T。

code.matlab
>> T=table([1;2;3;4],[5;6;7;8],'VariableNames',{'A' 'B'});
>> T.Properties.RowNames={'a';'b';'c';'d'};

使用值索引方式将第2行和第4行,第1列和第2列的值进行修改。

code.matlab
>> T([2 4],[1 2])={10 15;20 23}
T =
  4×2 table
         A     B
         __    __
    a     1     5
    b    10    15
    c     3     7
    d    20    23

重新创建表T。

code.matlab
>> T=table([1;2;3;4],[5;6;7;8],'VariableNames',{'A' 'B'});
>> T.Properties.RowNames={'a';'b';'c';'d'};

使用元胞索引方式将第2行和第4行,第1列和第2列的值进行修改。

code.matlab
>> T{[2 4],[1 2]}=[10 15;20 23]
T =
  4×2 table
         A     B
         __    __
    a     1     5
    b    10    15
    c     3     7
    d    20    23

【Python】

新建一个DataFrame df。

code.python
>>> df=pd.DataFrame([[1,5],[2,6],[3,7],[4,8]],index=['a','b','c','d'],columns=['A','B'])

用DataFrame对象的iloc方法修改第2行和第4行,第1列和第2列的值。

code.python
>>> df.iloc[[1,3],[0,1]]=[[10,15],[20,23]]
>>> df
    A   B
a   1   5
b  10  15
c   3   7
d  20  23

重新创建DataFrame df。

code.python
>>> df=pd.DataFrame([[1,5],[2,6],[3,7],[4,8]],index=['a','b','c','d'],columns=['A','B'])

用DataFrame对象的loc方法修改第2行和第4行,第1列和第2列的值。

code.python
>>> df.loc[['b','d'],['A','B']]=[[10,15],[20,23]]
>>> df
    A   B
a   1   5
b  10  15
c   3   7
d  20  23

修改连续区域的值

修改连续区域的值,先对连续区域进行索引(即切片),然后重新赋值。

【MATLAB】

下面创建表T。

code.matlab
>> T=table([1;2;3;4],[5;6;7;8],'VariableNames',{'A' 'B'});
>> T.Properties.RowNames={'a';'b';'c';'d'};

使用值索引方式将第2行到第3行,第1列到第2列的值进行修改。

code.matlab
>> T(2:3,1:2)={10 15;20 23}
T =
  4×2 table
    A     B
    __    __
     1     5
    10    15
    20    23
     4     8

重新创建表T。

code.matlab
>> T=table([1;2;3;4],[5;6;7;8],'VariableNames',{'A' 'B'});

使用元胞索引方式将第2行到第3行,第1列到第2列的值进行修改。

code.matlab
>> T{2:3,1:2}=[10 15;20 23]
T =
  4×2 table
    A     B
    __    __
     1     5
    10    15
    20    23
     4     8

【Python】

新建一个DataFrame df。

code.python
>>> df=pd.DataFrame([[1,5],[2,6],[3,7],[4,8]],index=['a','b','c','d'],columns=['A','B'])

用DataFrame对象的iloc方法修改第2行到第3行,第1列到第2列的值。

code.python
>>> df.iloc[1:3,0:2]=[[10,15],[20,23]]
>>> df
    A   B
a   1   5
b  10  15
c  20  23
d   4   8

重建DataFrame df。

code.python
>>> df=pd.DataFrame([[1,5],[2,6],[3,7],[4,8]],index=['a','b','c','d'],columns=['A','B'])

用DataFrame对象的loc方法修改第2行到第4行,第1列到第2列的值。

code.python
>>> df.loc['b':'c','A':'C']=[[10,15],[20,23]]
>>> df
    A   B
a   1   5
b  10  15
c  20  23
d   4   8

修改全部值

可以使用运算符或对象的方法修改表或DataFrame的全部值。

【MATLAB】

下面创建新表T。

code.matlab
>> T=table([1;2;3;4],[5;6;7;8],'VariableNames',{'A' 'B'});
>> T.Properties.RowNames={'a';'b';'c';'d'};

对表中的每个值求平方。

code.matlab
>> T.^2
ans =
  4×2 table
         A     B
         __    __
    a     1    25
    b     4    36
    c     9    49
    d    16    64

【Python】

创建DataFrame df。

code.python
>>> df=pd.DataFrame([[1,5],[2,6],[3,7],[4,8]],index=['a','b','c','d'],columns=['A','B'])

使用DataFrame对象的apply方法和匿名函数对每个值求平方。

code.python
>>> df=df.apply(lambda x:x**2)
>>> df
    A   B
a   1  25
b   4  36
c   9  49
d  16  64

重新创建DataFrame df。

code.python
>>> df=pd.DataFrame([[1,5],[2,6],[3,7],[4,8]],index=['a','b','c','d'],columns=['A','B'])

使用DataFrame对象的map方法和匿名函数求所有值的平方。

code.python
>>> df=df.map(lambda x:x**2)
>>> df
    A   B
a   1  25
b   4  36
c   9  49
d  16  64

数据排序

MATLAB和Python都提供了函数或对象的方法对表或DataFrame的行数据进行排序。根据参与排序的列的个数,可以有单条件排序和多条件排序。

【MATLAB】

下面新建表T。

code.matlab
>> T=table({'张三';'李四';'杨二';'王五'},[18;19;17;25],...
    [162;169;162;167], [116;103;131;133],'VariableNames',...
{'Name' 'Age' 'Height' 'Weight'});

使用sortrows函数,根据Height列数据的大小对表的行进行升序排列。

code.matlab
>> [B,index]=sortrows(T,"Height");
>> B
B =
  4×4 table
      Name      Age    Height    Weight
    ________    ___    ______    ______
    {'张三'}    18      162       116
    {'杨二'}    17      162       131
    {'王五'}    25      167       133
    {'李四'}    19      169       103

使用sortrows函数,根据第3列数据的大小对表的行进行降序排列。

code.matlab
>> [B,index]=sortrows(T,3,'descend');
>> B
B =
  4×4 table
      Name      Age    Height    Weight
    ________    ___    ______    ______
    {'李四'}    19      169       103
    {'王五'}    25      167       133
    {'张三'}    18      162       116
    {'杨二'}    17      162       131

使用sortrows函数,将Height列数据和Age列数据作为第1条件和第2条件对表的行进行升序排列。函数先根据Height列数据排序,对于Height数据相同的情况,再根据Age列数据的大小进行排序。

code.matlab
>> [B,index]=sortrows(T,["Height" "Age"]);
>> B
B =
  4×4 table
      Name      Age    Height    Weight
    ________    ___    ______    ______
    {'杨二'}    17      162       131
    {'张三'}    18      162       116
    {'王五'}    25      167       133
    {'李四'}    19      169       103

【Python】

创建一个DataFrame df。

code.python
>>> df=pd.DataFrame([['1','张三',18,162,116],['2','李四',19,169,103],['3','杨二',17,162,131],['4','王五',25,167,133]],columns=['ID','Name','Age','Height','Weight'])
>>> df.set_index('ID',inplace=True)

使用DataFrame大小的sort_values方法,根据Height列数据的大小对DataFrame的行进行升序排列。

code.python
>>> df.sort_values(by='Height')
   Name  Age  Height  Weight
ID
1    张三   18     162     116
3    杨二   17     162     131
4    王五   25     167     133
2    李四   19     169     103

使用DataFrame大小的sort_values方法,根据Height列数据的大小对DataFrame的行进行降序排列。

code.python
>>> df.sort_values(by='Height',ascending=False)
   Name  Age  Height  Weight
ID
2    李四   19     169     103
4    王五   25     167     133
1    张三   18     162     116
3    杨二   17     162     131

使用DataFrame大小的sort_values方法,将Height列数据和Age列数据作为第1条件和第2条件对表的行进行升序排列。方法先根据Height列数据排序,对于Height数据相同的情况,再根据Age列数据的大小进行排序。

code.python
>>> df.sort_values(by=['Height','Age'])
   Name  Age  Height  Weight
ID
3    杨二   17     162     131
1    张三   18     162     116
4    王五   25     167     133
2    李四   19     169     103

数据筛选

MATLAB和Python都提供了函数或对象的方法对表或DataFrame的行数据进行筛选。根据参与筛选的列的个数,可以有单条件筛选和多条件筛选。

【MATLAB】

MATLAB提供了rowfilter函数结合表的布尔索引对行数据进行筛选。下面创建一个表T。

code.matlab
>> T=table({'张三';'李四';'杨二';'王五'},[18;19;17;25],...
    [162;169;162;167], [116;103;131;133],'VariableNames',...
{'Name' 'Age' 'Height' 'Weight'});

用rowfilter函数创建一个关于表T的筛选对象。

code.matlab
>> rf=rowfilter(T);

使用布尔索引筛选出年龄大于或等于19岁的行数据。

code.matlab
>> T(rf.Age>=19,:)
ans =
  2×4 table
      Name      Age    Height    Weight
    ________    ___    ______    ______
    {'李四'}    19      169       103
    {'王五'}    25      167       133

对于多条件筛选的情况,下面筛选出年龄大于或等于18岁,身高大于162厘米的行数据。

code.matlab
>> T(rf.Age>=18 & rf.Height>162,:)
ans =
  2×4 table
      Name      Age    Height    Weight
    ________    ___    ______    ______
    {'李四'}    19      169       103
    {'王五'}    25      167       133

下面使用vartype函数结合表索引筛选出表中的数值类型的数据。

code.matlab
>> S=vartype('numeric');
>> T2=T(:,S)
T2 =
  4×3 table
    Age    Height    Weight
    ___    ______    ______
    18      162       116
    19      169       103
    17      162       131
    25      167       133

【Python】

Python的pandas包可以通过DataFrame的布尔索引、DataFrame对象的query方法、where方法和mask方法对行数据进行筛选。下面创建一个DataFrame df。

code.python
>>> df=pd.DataFrame([['1','张三',18,162,116],['2','李四',19,169,103],['3','杨二',17,162,131],['4','王五',25,167,133]],columns=['ID','Name','Age','Height','Weight'])
>>> df.set_index('ID',inplace=True)

使用布尔索引筛选出年龄大于或等于19岁的行数据。

code.python
>>> df[df['Age']>=19]
   Name  Age  Height  Weight
ID
2    李四   19     169     103
4    王五   25     167     133

使用布尔索引筛选出年龄大于或等于18岁,身高大于162厘米的行数据。

code.python
>>> df[(df['Age']>=18) & (df['Height']>162)]
   Name  Age  Height  Weight
ID
2    李四   19     169     103
4    王五   25     167     133

使用DataFrame对象的query方法筛选出年龄大于或等于19岁的行数据。

code.python
>>> df2=df.query('Age>=19')
df2
   Name  Age  Height  Weight
ID
2    李四   19     169     103
4    王五   25     167     133

使用DataFrame对象的where方法筛选出年龄大于或等于19岁的行数据。注意,筛选结果中不符合条件的数据会用空值表示。使用DataFrame对象的dropna方法删除有空值的行。how参数的值为“any”,表示行数据中只要有一个空值即判断为空行。

code.python
>>> df2=df.where(df['Age']>=19)
>>> df2=df2.dropna(how='any',axis=0)
df2
   Name   Age  Height  Weight
ID
2    李四  19.0   169.0   103.0
4    王五  25.0   167.0   133.0

使用DataFrame对象的mask方法筛选出年龄大于或等于19岁的行数据。注意,筛选结果中不符合条件的数据会用空值表示。使用DataFrame对象的dropna方法删除有空值的行。注意mask方法进行筛选判断时条件跟where方法是相反的。

code.python
>>> df2=df.mask(df['Age']<19)
>>> df2=df2.dropna(how='any',axis=0)
>>> df2
   Name   Age  Height  Weight
ID
2    李四  19.0   169.0   103.0
4    王五  25.0   167.0   133.0

下面使用DataFrame对象的select_dtypes方法筛选出表中数值类型的数据。

code.python
>>> import numpy as np
>>> df.select_dtypes(include=[np.number])
    Age  Height  Weight
ID
1    18     162     116
2    19     169     103
3    17     162     131
4    25     167     133

数据转置

表或DataFrame的转置,是将它们的第1行变为第1列,将最后1行变为最后1列,实际上是相对与对角线作对称变换。MATLAB和Python中都提供了相应的函数或方法进行操作。

【MATLAB】

MATLAB中可使用rows2vars函数对表进行转置操作。下面创建表T。

code.matlab
>> T=table({'张三';'李四';'杨二';'王五'},[18;19;17;25],...
    [162;169;162;167], [116;103;131;133],'VariableNames',...
{'Name' 'Age' 'Height' 'Weight'});
>> T.Properties.RowNames={'a';'b';'c';'d'};

使用rows2vars函数对T进行转置。

code.matlab
>> T2=rows2vars(T)
T2 =
  4×5 table
    OriginalVariableNames       a           b           c           d
    _____________________    ________    ________    ________    ________
         {'Name'  }          {'张三'}    {'李四'}     {'杨二'}     {'王五'}
         {'Age'   }          {[  18]}    {[  19]}    {[  17]}    {[  25]}
         {'Height'}          {[ 162]}    {[ 169]}    {[ 162]}    {[ 167]}
         {'Weight'}          {[ 116]}    {[ 103]}    {[ 131]}    {[ 133]}

【Python】

Python中使用pandas包内DataFrame对象的T属性或transpose方法实现DataFrame的转置。下面创建一个DataFrame df。

code.python
>>> df=pd.DataFrame([['1','张三',18,162,116],['2','李四',19,169,103],['3','杨二',17,162,131],['4','王五',25,167,133]],columns=['ID','Name','Age','Height','Weight'])
>>> df.set_index('ID',inplace=True)

用DataFrame对象的T属性对df进行转置。

code.python
>>> df2=df.T
>>> df2
ID        1    2    3    4
Name     张三   李四   杨二   王五
Age      18   19   17   25
Height  162  169  162  167
Weight  116  103  131  133

用DataFrame对象的transpose方法对df进行转置。

code.python
>>> df2=df.transpose()

得到跟上面相同的结果。

合并多表数据

用MATLAB和Python合并多个表或DataFrame时,根据连接键连接的方式不同,有内连接(inner)、外连接(outer)、左连接(left)和右连接(right)等4种连接方式,它们对应的集合关系如图10-4所示。

Document Image

图10-4 各连接方式对应的集合关系

从图中可以看出,内连接是求两个对象的交,外连接是求它们的并,左连接是左表加上二者的交,右连接是右表加上二者的交。

【MATLAB】

MATLAB中可用join函数和innerjoin函数求两个表的内连接,即求它们的交。

下面先创建两个表,即T1和T2。

code.matlab
>> T1=table({'张三';'李四';'杨二';'王五'},[18;19;17;25], ...
    [162;169;164;167],[116;103;131;133],'VariableNames', ...
    {'Name' 'Age' 'Height' 'Weight'});
>> T2=table({'张三';'李四';'杨二';'王五';'苏云'}, ...
    {'M';'M';'M';'M';'F'},[0;0;0;1;0], ...
    'VariableNames',{'Name' 'Gender' 'Married'});
>> T1
T1 =
  4×4 table
      Name      Age    Height    Weight
    ________    ___    ______    ______
    {'张三'}    18      162       116
    {'李四'}    19      169       103
    {'杨二'}    17      164       131
    {'王五'}    25      167       133
>> T2
T2 =
  5×3 table
      Name      Gender    Married
    ________    ______    _______
    {'张三'}    {'M'}        0
    {'李四'}    {'M'}        0
    {'杨二'}    {'M'}        0
    {'王五'}    {'M'}        1
    {'苏云'}    {'F'}        0

用join函数默认时求表T1和T2的内连接。这里连接键为Name列,下面表T3中的4个名字在T1和T2中都有,将它们对应的数据合并到T3。

code.matlab
>> T3=join(T1,T2)
T3 =
  4×6 table
      Name      Age    Height    Weight    Gender    Married
    ________    ___    ______    ______    ______    _______
    {'张三'}    18      162       116      {'M'}        0
    {'李四'}    19      169       103      {'M'}        0
    {'杨二'}    17      164       131      {'M'}        0
    {'王五'}    25      167       133      {'M'}        1

使用innerjoin函数也可以求T1和T2的内连接。

code.matlab
>> T4=innerjoin(T1,T2)
T4 =
  4×6 table
      Name      Age    Height    Weight    Gender    Married
    ________    ___    ______    ______    ______    _______
    {'张三'}    18      162       116      {'M'}        0
    {'李四'}    19      169       103      {'M'}        0
    {'杨二'}    17      164       131      {'M'}        0
    {'王五'}    25      167       133      {'M'}        1

使用outerjoin函数默认时求T1和T2的外连接,即求它们的并集。并集中包含两个表中的全部数据,没有的数据用缺失值表示。

code.matlab
>> T5=outerjoin(T1,T2)
T5 =
  5×7 table
     Name_T1      Age    Height    Weight    Name_T2     Gender    Married
    __________    ___    ______    ______    ________    ______    _______
    {'张三'  }     18     162       116      {'张三'}     {'M'}        0
    {'李四'  }     19     169       103      {'李四'}     {'M'}        0
    {'杨二'  }     17     164       131      {'杨二'}     {'M'}        0
    {'王五'  }     25     167       133      {'王五'}     {'M'}        1
    {0×0 char}    NaN     NaN       NaN      {'苏云'}    {'F'}        0

给outerjoin函数的“type”参数指定不同的值,可以实现外连接、左连接和右连接。下面指定“type”参数的值为“full”,结果为外连接。

code.matlab
>> T6=outerjoin(T1,T2,'type','full')
T6 =
  5×7 table
     Name_T1      Age    Height    Weight    Name_T2     Gender    Married
    __________    ___    ______    ______    ________    ______    _______
    {'张三'  }     18     162       116      {'张三'}     {'M'}        0
    {'李四'  }     19     169       103      {'李四'}     {'M'}        0
    {'杨二'  }     17     164       131      {'杨二'}     {'M'}        0
    {'王五'  }     25     167       133      {'王五'}     {'M'}        1
    {0×0 char}    NaN     NaN       NaN      {'苏云'}    {'F'}        0

给outerjoin函数的“type”参数指定值为“left”,结果为左连接。左连接时左表不变,在左表的基础上加上两个表的交集。

code.matlab
>> T7=outerjoin(T1,T2,'type','left')
T7 =
  4×7 table
    Name_T1     Age    Height    Weight    Name_T2     Gender    Married
    ________    ___    ______    ______    ________    ______    _______
    {'张三'}    18      162       116      {'张三'}     {'M'}        0
    {'李四'}    19      169       103      {'李四'}     {'M'}        0
    {'杨二'}    17      164       131      {'杨二'}     {'M'}        0
    {'王五'}    25      167       133      {'王五'}     {'M'}        1

给outerjoin函数的“type”参数指定值为“right”,结果为右连接。右连接时右表不变,在右表的基础上加上两个表的交集。

code.matlab
>> T8=outerjoin(T1,T2,'type','right')
T8 =
  5×7 table
     Name_T1      Age    Height    Weight    Name_T2     Gender    Married
    __________    ___    ______    ______    ________    ______    _______
    {'张三'  }     18     162       116      {'张三'}     {'M'}        0
    {'李四'  }     19     169       103      {'李四'}     {'M'}        0
    {'杨二'  }     17     164       131      {'杨二'}     {'M'}        0
    {'王五'  }     25     167       133      {'王五'}     {'M'}        1
    {0×0 char}    NaN     NaN       NaN      {'苏云'}    {'F'}        0

【Python】

Python中使用pandas包的merge函数可实现多个表的合并。根据merge函数how参数的取值的不同,实现不同方式的合并。

下面创建两个DataFrame df1和df2。

code.python
>>> df1=pd.DataFrame([['张三',18,162,116],['李四',19,169,103],['杨二',17,164,131],['王五',25,167,133]],columns=['Name','Age','Height','Weight'])
>>> df2=pd.DataFrame([['张三','M',0], ['李四','M',0], ['杨二','M',0], ['王五','M',1], ['苏云','F',0],],columns=['Name','Gender','Married'])
>>> df1
  Name  Age  Height  Weight
0   张三   18     162     116
1   李四   19     169     103
2   杨二   17     164     131
3   王五   25     167     133
>>> df2
  Name Gender  Married
0   张三      M        0
1   李四      M        0
2   杨二      M        0
3   王五      M        1
4   苏云      F        0

设置how参数的取值为“inner”,用merge函数对df1和df2进行内连接。这里连接键为Name列。

code.python
>>> df3=pd.merge(df1, df2, on='Name', how='inner')
>>> df3
  Name  Age  Height  Weight Gender  Married
0   张三   18     162     116      M        0
1   李四   19     169     103      M        0
2   杨二   17     164     131      M        0
3   王五   25     167     133      M        1

设置how参数的取值为“outer”,用merge函数对df1和df2进行外连接。

code.python
>>> df4=pd.merge(df1, df2, on='Name', how='outer')
>>> df4
  Name   Age  Height  Weight Gender  Married
0   张三  18.0   162.0   116.0      M        0
1   李四  19.0   169.0   103.0      M        0
2   杨二  17.0   164.0   131.0      M        0
3   王五  25.0   167.0   133.0      M        1
4   苏云   NaN     NaN     NaN      F        0

设置how参数的取值为“left”,用merge函数对df1和df2进行左连接。

code.python
>>> df5=pd.merge(df1, df2, on='Name', how='left')
>>> df5
  Name  Age  Height  Weight Gender  Married
0   张三   18     162     116      M        0
1   李四   19     169     103      M        0
2   杨二   17     164     131      M        0
3   王五   25     167     133      M        1

设置how参数的取值为“right”,用merge函数对df1和df2进行右连接。

code.python
>>> df6=pd.merge(df1, df2, on='Name', how='right')
>>> df6
  Name   Age  Height  Weight Gender  Married
0   张三  18.0   162.0   116.0      M        0
1   李四  19.0   169.0   103.0      M        0
2   杨二  17.0   164.0   131.0      M        0
3   王五  25.0   167.0   133.0      M        1
4   苏云   NaN     NaN     NaN      F        0

数据拼接

数据拼接,是将两个具有相同行数的表或DataFrame在水平方向拼接在一起组成一个新的表或DataFrame;或将两个具有相同列数的表或DataFrame在垂直方向拼接在一起组成一个新的表或DataFrame。

【MATLAB】

MATLAB中水平方向拼接两个表,将它们用中括号放到一个数组中就可以了,将两个表的变量用空格间隔。注意,进行水平方向拼接的两个表必须具有相同的行数。

下面创建两个表T1和T2。

code.matlab
>> T1=table({'张三';'李四';'杨二';'王五'},[18;19;17;25],...
    [162;169;164;167], [116;103;131;133],'VariableNames',...
{'Name' 'Age' 'Height' 'Weight'})
>> T2=table({'M';'M';'M';'M'},[0;0;0;1], ...
'VariableNames',{'Gender' 'Married'})

在水平方向上拼接T1和T2,组成新的表T。

code.matlab
>> T=[T1 T2]
T =
  4×6 table
      Name      Age    Height    Weight    Gender    Married
    ________    ___    ______    ______    ______    _______
    {'张三'}    18      162       116      {'M'}        0
    {'李四'}    19      169       103      {'M'}        0
    {'杨二'}    17      164       131      {'M'}        0
    {'王五'}    25      167       133      {'M'}        1

【Python】

Python中使用pandas包中的concat函数实现DataFrame的水平方向拼接。

下面创建两个DataFrame df1和df2。

code.python
>>> df1=pd.DataFrame([['张三',18,162,116],['李四',19,169,103],['杨二',17,164,131],['王五',25,167,133]],columns=['Name','Age','Height','Weight'])
>>> df2=pd.DataFrame([['M',0],['M',0],['F',0], ['M',1]],columns=['Gender','Married'])

用concat函数在水平方向拼接df1和df2,设置axis参数的值为1,表示拼接方向为水平方向。

code.python
>>> df3=pd.concat([df1,df2],axis=1)
>>> df3
  Name  Age  Height  Weight Gender  Married
0   张三   18     162     116      M        0
1   李四   19     169     103      M        0
2   杨二   17     164     131      F        0
3   王五   25     167     133      M        1

【MATLAB】

MATLAB中垂直方向拼接两个表,将它们用中括号放到一个数组中就可以了,将两个表的变量用分号间隔。注意,进行垂向拼接的两个表必须具有相同的列数。

下面创建第1个表T1。

code.matlab
>> T1=table({'张三';'李四';'杨二';'王五'},[18;19;17;25],...
    [162;169;164;167], [116;103;131;133],'VariableNames',...
{'Name' 'Age' 'Height' 'Weight'})
T1 =
  4×4 table
      Name      Age    Height    Weight
    ________    ___    ______    ______
    {'张三'}    18      162       116
    {'李四'}    19      169       103
    {'杨二'}    17      164       131
    {'王五'}    25      167       133

下面创建第2个表T2。

code.matlab
>> Name={'韩英';'赵军';'余成';'黄丽'};
>> Age=[19;22;20;18];
>> Height=[173;168;171;167];
>> Weight=[93;121;113;101];
>> T2=table(Name,Age,Height,Weight)
T2 =
  4×4 table
      Name      Age    Height    Weight
    ________    ___    ______    ______
    {'韩英'}    19      173        93
    {'赵军'}    22      168       121
    {'余成'}    20      171       113
    {'黄丽'}    18      167       101

垂向拼接两个表,组成新的表T。

code.matlab
>> T=[T1;T2]
T =
  8×4 table
      Name      Age    Height    Weight
    ________    ___    ______    ______
    {'张三'}    18      162       116
    {'李四'}    19      169       103
    {'杨二'}    17      164       131
    {'王五'}    25      167       133
    {'韩英'}    19      173        93
    {'赵军'}    22      168       121
    {'余成'}    20      171       113
    {'黄丽'}    18      167       101

【Python】

Python中可以使用DataFrame对象的_append方法垂向拼接两个DataFrame。要求这两个DataFrame具有相同的列数。

下面创建两个DataFrame df1和df2。

code.python
>>> df1=pd.DataFrame([['张三',18,162,116],['李四',19,169,103],['杨二',17,164,131],['王五',25,167,133]],columns=['Name','Age','Height','Weight'])
>>> df2=pd.DataFrame([['韩英',19,173,93],['赵军',22,168,121],['余成',20,171,113],['黄丽',18,167,101]],columns=['Name','Age','Height','Weight'])
>>> df1
  Name  Age  Height  Weight
0   张三   18     162     116
1   李四   19     169     103
2   杨二   17     164     131
3   王五   25     167     133
>>> df2
  Name  Age  Height  Weight
0   韩英   19     173      93
1   赵军   22     168     121
2   余成   20     171     113
3   黄丽   18     167     101

使用df1对象的_append方法垂向拼接df2。注意,在pandas 2.x版本中DataFrame对象已经没有append方法了,可以用_append方法实现。[大谦MATLAB,dqmatlab点com]

code.python
>>> df3=df1._append(df2)
>>> df3
  Name  Age  Height  Weight
0   张三   18     162     116
1   李四   19     169     103
2   杨二   17     164     131
3   王五   25     167     133
0   韩英   19     173      93
1   赵军   22     168     121
2   余成   20     171     113
3   黄丽   18     167     101