使用pandas进行简单数据处理的常用指令

一、背景

pandas是基于numpy的一种工具,是为解决数据分析任务而创建的。pandas提供了大量实用的函数用于分析数据,具体可参考官方文档。官网也有基础入门的十分钟指导,具体可见:10 minutes to pandas

二、常用场景

1. 文件输入输出

pandas提供大量方便的IO操作,以读写csv文件为例:

# 读csv文件
import pandas as pd
df = pd.read_csv('filename.csv')

# 写csv文件,不输出索引
df.to_csv('target.csv', index=False)  

# 写csv文件,输出索引
df.to_csv('target.csv', index=True)  

上面代码中df是pandas.DataFrame的一个实例。

读写excel文件的方式与读写csv文件类似。读excel文件此处不再赘述,可参考官方文档pandas.read_excel。但写excel就需要注意了,我们有时候有需要将处理好的几份数据(DataFrame)写入到同一个excel表格中,以sheet区别,这时候需要使用下面的写法:

with pd.ExcelWriter('filename.xlsx') as writer:
    df1.to_excel(writer, 'sheet_name_1')
    df2.to_excel(writer, 'sheet_name_2')

上面的代码中,将df1写到filename.xlsx的sheet_name_1表,将df2写到filename.xlsx的sheet_name_2表。如果使用以下的写法,不使用with语句,则后一次写入会把前一次写入覆盖。即filename.xlsx只有一个表sheet_name_2

df1.to_excel('filename.xlsx', 'sheet_name_1')
df2.to_excel('filename.xlsx', 'sheet_name_2')

2. 获取某行、某列、某个位置的数据

要获取某行的数据,可以直接使用下标,如下取前面两行的数据:

>>> df
       name        toy       born
0    Alfred        NaN        NaT
1    Batman  Batmobile 1940-04-25
2  Catwoman   Bullwhip        NaT
>>> df[0:2]
     name        toy       born
0  Alfred        NaN        NaT
1  Batman  Batmobile 1940-04-25

如果要获取某列的数据,可以直接使用列名,如下取toy列的数据:

>>> df
       name        toy       born
0    Alfred        NaN        NaT
1    Batman  Batmobile 1940-04-25
2  Catwoman   Bullwhip        NaT
>>> df['name']
0      Alfred
1      Batman
2    Catwoman
Name: name, dtype: object

如果要获取某两列的数据,可以直接列名的列表,如下取toy列和born列的数据:

>>> df[['name','born']]
       name       born
0    Alfred        NaT
1    Batman 1940-04-25
2  Catwoman        NaT

结合前面几种情况,如果想取某列某行,如取第3行的toy列的数据,可以执行如下指令:

>>> df
       name        toy       born
0    Alfred        NaN        NaT
1    Batman  Batmobile 1940-04-25
2  Catwoman   Bullwhip        NaT
>>> df[2:3]['born']
2   NaT
Name: born, dtype: datetime64[ns]

如果想要获取某列中某些范围的数据,可以直接使用条件判断,如下:

>>> data = {'Name': ['Jai', 'Princi', 'Gaurav', 'Anuj'],
...         'Height': [5.1, 6.2, 5.1, 5.2],
...         'Qualification': ['Msc', 'MA', 'Msc', 'Msc']}
>>> df = pd.DataFrame(data)
>>> df
     Name  Height Qualification
0     Jai     5.1           Msc
1  Princi     6.2            MA
2  Gaurav     5.1           Msc
3    Anuj     5.2           Msc
>>> df[df['Height'] == 5.1]
     Name  Height Qualification
0     Jai     5.1           Msc
2  Gaurav     5.1           Msc
>>> df[df['Height'] > 5.1]
     Name  Height Qualification
1  Princi     6.2            MA
3    Anuj     5.2           Msc

3. 对某列数据进行排序

对数据进行排序主要使用DataFrame.sort_values接口,常用的是对某一列进行升序或降序排列,如下:

import pandas as pd
import numpy as np
df = pd.DataFrame({
    'col1': ['A', 'A', 'B', np.nan, 'D', 'C'],
    'col2': [2, 1, 9, 8, 7, 4],
    'col3': [0, 1, 9, 4, 2, 3],
    'col4': ['a', 'B', 'c', 'D', 'e', 'F']
})
df

df的打印值为:

>>> df
  col1  col2  col3 col4
0    A     2     0    a
1    A     1     1    B
2    B     9     9    c
3  NaN     8     4    D
4    D     7     2    e
5    C     4     3    F

对第一列进行升序排序:

>>> df.sort_values(by=['col1'])
  col1  col2  col3 col4
0    A     2     0    a
1    A     1     1    B
2    B     9     9    c
5    C     4     3    F
4    D     7     2    e
3  NaN     8     4    D

对第一列进行降序排序:

>>> df.sort_values(by=['col1'], ascending=False)
  col1  col2  col3 col4
4    D     7     2    e
5    C     4     3    F
2    B     9     9    c
0    A     2     0    a
1    A     1     1    B
3  NaN     8     4    D

从上面的两个例子中可以发现空值(NaN)无论是升序还是降序排序都是排在数据集尾部的。如果想把空值排在前面,可以指定参数na_position的值为first,如下:

>>> df.sort_values(by=['col1'], ascending=False, na_position='first')
  col1  col2  col3 col4
3  NaN     8     4    D
4    D     7     2    e
5    C     4     3    F
2    B     9     9    c
0    A     2     0    a
1    A     1     1    B

另外一个可能忽略的点是,如果sort_values不指定inplace参数,即原地排序,那么pandas排序时并不会修改原数据集的值,而是将新值返回,如下:

>>> df1=df.sort_values(by=['col1'], ascending=False, na_position='first')
>>> df
  col1  col2  col3 col4
0    A     2     0    a
1    A     1     1    B
2    B     9     9    c
3  NaN     8     4    D
4    D     7     2    e
5    C     4     3    F

4. 去除列中的空值

去除数据集中列的空值主要使用DataFrame.dropna()函数,即drop nan。如下第2列和第3列中均有空值,涉及第1行和第3行。因此在执行dropna之后,只保留了第二行的数据:

>>> df = pd.DataFrame({"name": ['Alfred', 'Batman', 'Catwoman'],
...                    "toy": [np.nan, 'Batmobile', 'Bullwhip'],
...                    "born": [pd.NaT, pd.Timestamp("1940-04-25"),
...                             pd.NaT]})
>>> df
       name        toy       born
0    Alfred        NaN        NaT
1    Batman  Batmobile 1940-04-25
2  Catwoman   Bullwhip        NaT
>>> df.dropna()
     name        toy       born
1  Batman  Batmobile 1940-04-25

若要指定只去除某一列中的空值,可以使用subset参数。如下指定去除toy列的空值:

>>> df.dropna(subset='toy')
       name        toy       born
1    Batman  Batmobile 1940-04-25
2  Catwoman   Bullwhip        NaT

5. 计数

pandas的计数使用DataFrame.value_counts()接口。使用方法比较简单,如果想指定对某一列进行计数,在value_counts的subset参数中指定即可;如果无需指定对某一列进行计数,可直接调用该函数,如下:

>>> df = pd.DataFrame({'first_name': ['John', 'Anne', 'John', 'Beth'],
...                    'middle_name': ['Smith', pd.NA, pd.NA, 'Louise']})
>>> df
  first_name middle_name
0       John       Smith
1       Anne        <NA>
2       John        <NA>
3       Beth      Louise
>>> df.value_counts()
first_name  middle_name
Beth        Louise         1
John        Smith          1
Name: count, dtype: int64
>>> df.value_counts(dropna=False)
first_name  middle_name
Anne        NaN            1
Beth        Louise         1
John        Smith          1
            NaN            1
Name: count, dtype: int64
>>> df.value_counts(subset='first_name')
first_name
John    2
Anne    1
Beth    1
Name: count, dtype: int64

如果想取某个值的计数值,则可以直接使用下标指定想获取计数的值即可,如下:

>>> df.value_counts(subset='first_name')['John']
2

6. 行的连接

数据行的连接是使用pandas.concat()接口,如下:

>>> s1 = pd.Series(['a', 'b'])
>>> s2 = pd.Series(['c', 'd'])
>>> pd.concat([s1, s2])
0    a
1    b
0    c
1    d
dtype: object

7. 列的连接

列的连接更简单,直接使用赋值语句即可。如下:

>>> data = {'Name': ['Jai', 'Princi', 'Gaurav', 'Anuj'],
...         'Height': [5.1, 6.2, 5.1, 5.2],
...         'Qualification': ['Msc', 'MA', 'Msc', 'Msc']}
>>> df = pd.DataFrame(data)
>>> address = ['Delhi', 'Bangalore', 'Chennai', 'Patna']
>>> df['Address'] = address
>>> df
     Name  Height Qualification    Address
0     Jai     5.1           Msc      Delhi
1  Princi     6.2            MA  Bangalore
2  Gaurav     5.1           Msc    Chennai
3    Anuj     5.2           Msc      Patna

三、参考资料

  1. pandas官方API文档
  2. pandas百度百科
  3. Adding new column to existing DataFrame in Pandas

留言

您的邮箱地址不会被公开。 必填项已用 * 标注