首页 > pandas 阅读数:39

pandas DataFrame对象创建及常用操作

DataFrame 对象的数据结构与工作表(最常见的是 Excel 工作表)极为相似,其设计初衷是将 Series 的使用场景由一维扩展到多维。DataFrame 数据结构是由按一定顺序排列的多列数据组成的,各列的数据类型可以有所不同(数值、字符串或布尔值等)。

DataFrame 的数据结构特点如下:
  • DataFrame 由共用相同索引的一组列组成;
  • DataFrame 是一个表格型的数据结构,每列值类型可以不同;
  • DataFrame 常用于表达二维数据,也可表达多维数据;
  • DataFrame 既有行索引(index),也有列索引(columns),其中行索引的数组与行相关,它与 Series 的索引数组相似,每个标签与标签所在行的所有元素相关联。而列索引包含一系列列标签,每个标签与一列数据相关联。

例如用于表示姓名、性别和年龄的 DataFrame 数据结构,如图 1 所示。

DataFrame数据结构
图 1:DataFrame 数据结构

DataFrame 还可以理解为一个由 Series 组成的字典,其中每一列的名称为字典的键,形成 DataFrame 列的 Series 作为字典的值。进一步来说,每个 Series 的所有元素映射到叫作 index 的标签数组。

1. 创建 DataFrame 对象

使用 DataFrame() 构造函数可创建 DataFrame 对象,DataFrame() 构造函数的格式如下:

pandas.DataFrame(data[,index[,columns]])

函数中的参数说明如下:
  • data 是输入给 DataFrame 构造器的数据,见表 1。

表 1:输入给DataFrame构造器的数据
类型 说明
二维 ndarray 数据矩阵,还可以传入行标和列标
由数组、列表或元组组成的字典 每个序列会变成 DataFrame 的一列,所有序列的长度必须相同
NumPy 的结构化/记录数组 类似于“由数组组成的字典”
由 Series 组成的字典 每个 Series 会组成一列,如果没有显示指定索引:则各 Series 的索引会被合并成结果的行索引
由字典组成的字典 各内层字典会成为一列。键会被合并成结果的行索引,与“由 Series 组成的字典”的情况一样
字典或 Series 的列表 各项将会成为 DataFrame 的一行。字典键或 Series 索引的并集将会成为 DataFrame 的列标
由列表或元组组成的列表 类似于"二维 ndarray,'
另一个 DataFrame 该 DataFrame 的索引将会被沿用,除非显示指定了其他索引
NumPy 的 MaskedArray
类似于“二维 ndarray”的情况,只是掩码值在结果 DataFeme 会变成 NA/ 缺失

  • index 是 DataFrame 对象中行索引的标签。
  • columns 是 DataFrame 对象中列索引的标签。

1) 用字典生成 DataFrame 对象

新建 DataFrame 对象最常用的方法是传递一个字典对象给 DataFrame() 构造函数。字典对象以每一列的名称作为键,每个键都有一个数组或列表或元组作为值。

例如,创建一个包含学生姓名、性别和年龄的 DataFrame 对象。首先创建一个字典对象,然后将字典对象传入给 DataFrame() 构造函数。在 Jupyter Notebook 下输入下列代码:
In [1]:  import pandas as pd
In [2]:  dt = {'name':['张艳','李明','王勇'],'sex':['False','True', 'True'],'age':[18,20,19]}
In [3]:  df = pd.DataFrame(dt)
In [4]:  df
Out[4]:
             name    sex     age
         0   张艳  False      18
         1   李明  True       20
         2   王勇  True       19

如果只需要用字典对象中部分列来创建 DataFrame 对象,可通过 columns 参数指定字典对象列名,其示例代码如下:
In [5]:  df = pd.DataFrame(dt,columns=['name','age'])
In [6]:  df
Out[6]:
            name  age
         0  张艳   18
         1  李明   20
         2  王勇   19

DataFrame 对象与 Series 相同,如果 index 数组没有明确指定标签,pandas 也会自动为其添加一列从 0 开始的数值作为索引。如果想用标签作为 DataFrame 的索引,则要将标签放到数组中,赋值给 index 选项,其示例代码如下:
In [7]:  df = pd.DataFrame(dt,index=['a','b','c'],columns=['name','age'])
In [8]:  df
Out[8]:
              name   age
         a   张艳     18
         b   李明     20
         c   王勇     19

2)  嵌套字典生成 DataFrame 对象

嵌套字典是 Python 广泛使用的数据结构,例如用嵌套字典表示学生姓名和年龄。

dt = {'name':{'a':'张艳','b':'李明','c':'王勇'},'age':{'a':18,'b':20}}


如果将这种数据结构直接作为参数传递给 DataFrame() 构造函数,pandas 就会将外部的键解释成列名称,将内部的键解释为用作索引的标签。

解释嵌套结构时,可能并非所有的位置都有相应的元素存在,pandas 会用 NaN 填补缺失的元素,其示例代码如下:
In [9]:  dt = {'name':{'a':'张艳','b':'李明','c':'王勇'},'age':{'a':18,'b':20}}
In [10]:  df= pd.DataFrame(dt)
Out[10]:  df
             name    age
          a  张艳   18.0
          b  李明   20.0
          c  王勇    NaN

3) 用二维数组生成 DataFrame 对象

利用 numpy.arange(8).reshape(2,4) 创建 2 行 4 列的二维数组,然后将其传递给 DataFrame() 构造函数,可创建一个新 DataFrame 对象,其示例代码如下:
In [11]:  import numpy as np
In [12]:  df = pd.DataFrame(np.arange(8).reshape(2,4))
In [13]:  df
Out[13]:
             0  1  2  3
          0  0  2  2  3
          1  4  5  6  7

4) 用由 Series 组成的字典生成 DataFrame 对象

将由 Series 组成的字典传递给 DataFrame() 构造函数,也可创建一个新的 DataFrame 对象,例如,创建一个产品价格表的 DataFrame 对象,其示例代码如下:
In [14]:  dt = {'product':pd.Series(['电视机','空调','洗衣机','电脑']),'price':pd.Series([2300,1980,780])}
In [15]:  df = pd.DataFrame(dt)
In [16]:  df
Out[16]:
              product   price
          0    电视机   2300.0
          1      空调   1980.0
          2    洗衣机    780.0
          3      电脑      NaN

从运行结果可见,DataFrame 的每个列是由各个 Series 组成,DataFrame 的行索引是由各个 Series 的索引合并组成的。与用嵌套字典生成 DataFrame 对象相同,在解释 Series 数据结构时,可能并非所有的位置都有相应的元素存在,pandas 会用 NaN 填补缺失的元素。

2. 利用 DataFrame 属性选择元素

1) 选择所有列的名称和索引列表

DataFrame 属性有 index 和 columns,调用 columns 属性可获取 DataFrame 对象所有列的名称,而要获取 DataFrame 的索引列表,则调用 index 属性即可,其示例代码如下:
In [17]:  df.columns
Out[17]:  Index(['product', 'price'], dtype='object')
In [18]:  df.index
Out[18]:  RangeIndex(start=0, stop=4, step=1)

2) 选择所有的元素

如果想获取存储在数据结构中的元素,可使用 values 属性获取所有的元素。其示例代码如下:
In [19]:  df.values
Out[19]:  array([['电视机', 2300.0],
                 ['空调', 1980.0],
                 ['洗衣机', 780.0],
                 ['电脑', NaN]], dtype=object)

3) 选择一列元素

如果想选择一列的内容,可把这一列的名称作为索引,或者用列名称作为 DataFrame 实例的属性,其示例代码如下:
In [20]:  df['price']
Out[20]:  0    2300.0
          1    1980.0
          2     780.0
          3       NaN
          Name: price, dtype: float64
In [21]:  df.price
df.price 和 df['price'] 的输出结果相同,返回值为 Series 对象的 price 列的内容。

4) 选择一行元素

如果想选择一行的内容,利用 iloc 属性和行的索引值就能获取到。例如,获取产品价格表第 2 行数据,其示例代码如下:
In [22]:  df.iloc[1]
Out[22]:  product       空调
               price        1980
               Name: 1, dtype: object
返回值同样是一个 Series 对象,其中列的名称已经变为索引数组的标签,而列中的元素变为 Series 数据部分。

5) 选择多行元素

利用 iloc 属性和一个数组的切片来指定 DataFrame 实例的索引列表的取值范围,从而可选取多行元素。

例如,选择产品价格表的 DataFrame 实例中第 1 行和第 3 行元素,其示例代码如下:
In [23]:  df.iloc[0:4:2]
Out[23]:
             product      price
          0   电视机     2300.0
          2   洗衣机      780.0
其中,iloc[0:4:2] 属性中数组切片 0:4:2,表示起始值是 0,终止值是 4(不包含 4 ),步长是 2,所取行数是 0 和 2。

6) 选择 DataFrame 实例中的一个元素或一个范围内的元素

如果想获取存储在 DataFrame 实例中的一个元素,需要依次指定元素所在的列名称、行的索引值或标签。例如,用 df['product'][1] 可选择产品价格表中产品名称为“空调”的元素。

如果想获取存储在 DataFrame 实例中某个范围内的元素,可用切片方式指定元素所在的列名称的范围和行的索引值或标签的范围。例如,用 df['product'][1:3] 可选择产品价格表中产品名称为“空调”和“洗衣机”的元素。

3. 给 DataFrame 赋值

1) 指定行索引和列索引标签

前面讲过 index 属性可以指定 DataFrame 结构中的索引数组,用 columns 属性可以指定包含列名称的行,而使用 name 属性,通过对一个 DataFrame 实例进行 df 设置( df.index.name 和 df.columns.name)就可以为 DataFrame 结构指定行索引标签和列索引标签。

例如,对产品价格表指定行索引标签和列索引标签,其示例代码如下:
In [24]:  df.index.name = 'id'
In [25]:  df.columns.name = 'item
In [26]:  df
Out[26]:
              item   product   price
                id
                 0  电视机    2300.0
                 1    空调    1980.0
                 2  洗衣机     780.0
                 3    电脑       NaN

2) 添加一列元素

为 DataFrame 实例添加一列元素的方法就是指定 DataFrame 实例新列的名称,并为其赋值即可。例如,为产品价格增加一个折扣率列,其示例代码如下:
In [27]:  df['discount']=[0.9,0.85,0.95,1]
In [28]:  df
Out[28]:
            item    product  price  discount
              id
               0    电视机  2300.0       0.90
               1      空调  1980.0       0.85
               2    洗衣机   780.0       0.95
               3      电脑     NaN       1.00

或者用 insert() 函数在指定位置添加一列元素。例如,在折扣率列后面,添加一列价格(“price”)乘以折扣率(“discount”)的实际价格(“Actual_price”)列,其示例代码如下:
In [29]:  df.insert(3,'Actual_price',df['price']*df['discount'])
In [30]:  df
Out[30]:
            item    product     price    discount   Actual_price
              id
               0     电视机    2300.0       0.90          2070.0
               1       空调    1980.0       0.85          1683.0
               2     洗衣机     780.0       0.95           741.0
               3       电脑       NaN       1.00             NaN

3) 添加一行元素

为 DataFrame 实例添加一行元素的方法就是使用 loc 属性为 DataFrame 实例新添加一行,并为此行赋值即可。例如,为产品价格增加一个手机产品的价格行,其示例代码如下:
In [31]:  df.loc['add_row'] = ['手机',1900,1,1900]
In [32]:  df
Out[32]:
                 item    product    price   discount    Actual_price
                   id
                    0     电视机   2300.0       0.90          2070.0
                    1       空调   1980.0       0.85          1683.0
                    2     洗衣机    780.0       0.95           741.0
                    3       电脑      NaN       1.00             NaN
              add_row       手机   1900.0       1.00          1900.0

4) 修改一行元素

修改 DataFrame 对象中的一行元素,只需要使用 loc 属性指定 DataFrame 实例中行索引,并为此行赋值即可。例如,修改产品价格中电脑一行的数据,其示例代码如下:
In [33]:  df.loc[3] = ['电脑',4500,1,4500]
In [34]:  df
Out[34]:
             item     product     price    iscount  Actual_price
               id
                0     电视机      2300.0      0.90       2070.0
                1       空调      1980.0      0.85       1683.0
                2     洗衣机       780.0      0.95        741.0
                3       电脑      4500.0      1.00       4500.0
          add_row       手机      1900.0      1.00       1900.0

5) 修改一列元素或一个元素

修改 DataFrame 实例中的一列元素,只要指定 DataFrame 实例中列名称,将要更新的一列元素存放到数组中,然后将此数组赋值给这一列即可。

例如,修改产品价格中的价格为新价格 [3000,2300,560,5600],其示例代码如下:
In [35]:  df['price']=[3000,2300,560,5600,1880]
In [36]:  df
Out[36]:
             item     product   price  discount     Actual_price
               id
                0    电视机     3000       0.90           2070.0
                1       空调    2300       0.85           1683.0
                2     洗衣机     560       0.95            741.0
                3       电脑    5600       1.00           4500.0
          add_row       手机    1880       1.00           1900.0
修改一个元素,只需要选择该元素,直接给其赋值即可。例如 df['discount'][1]=0.96。

4. 删除元素

1) 使用 del 命令删除一列元素

如果要删除一整列的所有数据,使用 del 命令。例如,删除产品价格中的实际价格列,其示例代码如下:
In [37]:  del df['Actual_price']
In [38]:  df
Out[38]:
             item   product   price      discou
               id
                0    电视机    3000        0.90
                1      空调    2300        0.85
                2    洗衣机     560        0.95
                3      电脑    5600        1.00
          add_row      手机    1880        1.00

2) 使用 pop() 函数删除一列元素

pop() 函数可以将所选列从原数据块中删除,原数据块不再保留该列。例如,使用 pop() 函数删除折扣率列,其示例代码如下:
In [39]:  df.pop('discount')
Out[39]:  id
           0          0.90
           1          0.85
           2          0.95            3          1.00
           add_row    1.00
           Name: discount, dtype: float64

3) 使用 drop() 函数删除一列元素或删除一行元素

在 drop() 函数中有两个参数,一个参数是 axis,当参数 axis=1 时,则删除列元素;当 axis=0 时,则删除行元素。还有一个参数是 inplace,当 inplace 为 True 时,drop() 函数执行内部删除,不返回任何值,原数据发生改变;当 inplace 为 False 时,原数据不会发生改变,只是输出新变量删除。

例如,先添加 1 列折扣率列,然后再用 drop() 函数设置参数 axis=1 和 inplace=True 删除折扣率的列元素,其示例代码如下:
In [40]:  df['discount']=0.94
In [41]:  df.drop(['discount'],axis=1,inplace=True)

如果要删除一行,则设置 axis=0,并指定删除的行索引或行标签。例如,删除行标签为 add_row 的一行元素,其示例代码如下:
In [42]:  df.drop(['add_row'],axis=0,inplace=True)

如果要删除多行,除了设置 axis=0 外,还要指定删除的行索引或行标签,例如,删除第 1 行和第 3 行元素,其示例代码如下:
In [43]:  df.drop([0,2],axis=0,inplace=True)

5. 筛选元素

对于 DataFrame 对象,也可以通过指定条件来筛选元素。例如,筛选出产品价格中价格大于 2000 元的产品信息,其示例代码如下:
In [44]:  df[df['price']>2000]
Out[44]:
          item    product   price
            id
             0     电视机    3000
             1       空调    2300
             3       电脑    5600

例如,筛选出产品价格中所有元素都小于 2000 元的产品信息,其示例代码如下:
In [45]:  df[df<2000]
Out[45]:
          item    product   price
            id
             0    电视机      NaN
             1      空调      NaN
             2    洗衣机      560
             3      电脑      NaN
返回的 DataFrame 对象中只包含满足条件的数字,各元素的位置保持不变,其他不符合条件的元素替换成 NaN。

6. 判断元素是否存在

使用 isin() 函数可以判断给定的一列元素是否包含在 DataFrame 结构中,如果给定的元素包含在数据结构中,isin() 函数返回是 True,否则返回是 False。利用此函数可以筛选 DataFrame 列中的数据。

例如判断产品价格中是否存在“电脑”和 2300 这两个元素,并返回满足条件的元素,其示例代码如下:
In [46]:  df[df.isin(['电脑',2300])]
Out[46]:
          item    product    price
            id
             0       NaN       NaN
             1       NaN    2300.0
             2       NaN       NaN
             3      电脑       NaN

7. DataFrame 转置

DataFrame 数据结构类似于表格数据结构,在处理表格数据时,常常会用到转置操作,即将列变成行,行变成列。pandas 提供了一种简单的转置方法,就是通过调用T属性获得 DataFrame 对象的转置形式。

例如将产品价格数据结构进行转置操作,其示例代码如下:
In [47]:  df.T
Out[47]:
               id      0     1       2         3
              item
            product   电视机   空调   洗衣机      电脑
            price     3000  2300      560       5600