Pandas的用法详细总结_官方Tutorial版

前言

  • 本篇博客是我在Pandas官网的新手教程上学习时的学习笔记,少掉了关于pandas的绘图,主要是因为Matplotlib这个库我还没怎么学,等我这几两天学一学,有空了再来补这坑

  • pandas官网tutorials官方新手入门教程链接在这,学东西还是直接看官网文档快,就是看英文比较费时间。

在这里插入图片描述

Pandas基本操作

pandas用DataFrame来存储处理数据

A DataFrame is a 2-dimensional data structure that can store data of different types (including characters, integers, floating point values, categorical data and more) in columns. It is similar to a spreadsheet, a SQL table or the data.frame in R.

DataFrame中的每一列被称为一个Series。

  1. 可以直接创建一个系列,也可以在创建数据表的过程中创建系列
In [2]: df = pd.DataFrame(
   ...:     {
   ...:         "Name": [
   ...:             "Braund, Mr. Owen Harris",
   ...:             "Allen, Mr. William Henry",
   ...:             "Bonnell, Miss. Elizabeth",
   ...:         ],
   ...:         "Age": [22, 35, 58],
   ...:         "Sex": ["male", "male", "female"],
   ...:     }
   ...: )
   ...: 

In [3]: df
Out[3]: 
                       Name  Age     Sex
0   Braund, Mr. Owen Harris   22    male
1  Allen, Mr. William Henry   35    male
2  Bonnell, Miss. Elizabeth   58  female
  1. 可以直接根据Serial的名称直接在一个DataFrame中取出一整个列的数据,可以理解为Python字典中的根据键直接取出值。

When selecting a single column of a pandas DataFrame, the result is a pandas Series. To select the column, use the column label in between square brackets [].

In [4]: df["Age"]
Out[4]: 
0    22
1    35
2    58
Name: Age, dtype: int64
  1. 在DataFrame中Series是没有序号的(列标签),但是Series中的行数据是有标签的

A pandas Series has no column labels, as it is just a single column of a DataFrame. A Series does have row labels.

有了DataFrame和Series的概念后,我们就可以针对它们进行一些统计学的操作

  1. 得到系列中的最大值
In [7]: df["Age"].max()  #通过在数据表中选择列
Out[7]: 58
In [8]: ages.max()
Out[8]: 58
  1. 可以数据表和系列的行数和列数进行查看,对数据表shape得到的是行数和列数,对系列shape只得到行数,因为系列只有一维,只能返回行数。同样shape也只是数据表和系列i的一个属性,不用带括号
titanic["Age"].shape
  1. 对数据表中的数值数据进行基本统计,以便快速了解数据
In [9]: df.describe()
Out[9]: 
             Age
count   3.000000
mean   38.333333
std    18.230012
min    22.000000
25%    28.500000
50%    35.000000
75%    46.500000
max    58.000000
  1. 如果想要获取数据表中的信息摘要,那么我们可以使用,数据表中内置方法.info()
In [9]: titanic.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
 #   Column       Non-Null Count  Dtype  
---  ------       --------------  -----  
 0   PassengerId  891 non-null    int64  
 1   Survived     891 non-null    int64  
 2   Pclass       891 non-null    int64  
 3   Name         891 non-null    object 
 4   Sex          891 non-null    object 
 5   Age          714 non-null    float64
 6   SibSp        891 non-null    int64  
 7   Parch        891 non-null    int64  
 8   Ticket       891 non-null    object 
 9   Fare         891 non-null    float64
 10  Cabin        204 non-null    object 
 11  Embarked     889 non-null    object 
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB

实际上它也是一个数据表。数据表信息摘要中有:

  1. 使用.info()方法对象的类型,和Python中的type(data)方法返回结果类似
  2. 数据表中行数和行索引变化范围
  3. 数据表中的Series列数的数量
  4. 每一列数据的非空值和数据类型,
  5. 所有不同数据类型的总数
  6. 存储这个数据表大概需要多少内存空间。

对文件的读取操作

pandas可以从不同文件中读取数据,然后将其转换为DataFrame形式存储。其读取的方法就是在不同文件格式缩写前加上_read前缀。
titanic = pd.read_csv(“data/titanic.csv”)

pandas provides the read_csv() function to read data stored as a csv file into a pandas DataFrame. pandas supports many different file formats or data sources out of the box (csv, excel, sql, json, parquet, …), each of them with the prefix read_*.

  1. 读取出来的数据默认是显示前五行和后五行,不对DataFrame使用任何方法而是直接打印就是这样的默认显示。如果我们需要有其他的显示要求,如光显示前几行,或者光显示后几行,就是需要好使用其自带的head() 和tail() 方法来指定了。
  2. 可以对数据表进行数据类型格式显示,使用 .dtypes即可 。.dtype是DataFrame或Series中的属性,而不是一个方法,所以并不需要括号。

不光可以从外部输入文件,pandas也可以将数据表转换为特定格式的文件导出,外部读入是read_* ,内部导出就是to_* 。如转换为电子表格,使用to_excel()即可,该方法会将数据表转换为.excel文件。此时再用read_excel()就又可以等效还原回来了

Whereas read_* functions are used to read data to pandas, the to_* methods are used to store data.

titanic.to_excel(“titanic.xlsx”, sheet_name=“passengers”, index=False)
#index= False 表示不会把数据表中的行索引数据保存在excel中

在数据表中选择子集

1. 在数据表中选择列(Series)

image.png

  1. 选择单个列,直接在方括号[]中填入对应的列表名称即可
In [4]: ages = titanic["Age"]

In [5]: ages.head()
Out[5]: 
0    22.0
1    38.0
2    26.0
3    35.0
4    35.0
Name: Age, dtype: float64
  1. 要在数据表中选择多个列,就可以在方括号中填入包含多个列表名称的列表,即在方括号中的方括号,返回结果用DataFrame表示
age_sex = titanic[["Age", "Sex"]]
In [8]: age_sex = titanic[["Age", "Sex"]]

In [9]: age_sex.head()
Out[9]: 
Age     Sex
0  22.0    male
1  38.0  female
2  26.0  female
3  35.0  female
4  35.0    male

2. 在数据表中过滤出符合要求的行

image.png

  1. 可以直接在数据表的方括号中填写逻辑表达式,逻辑表达式会对数据表中的每一行进行检查,若符合条件即Ture,那么就会被过滤出来在新的数据表中。
In [12]: above_35 = titanic[titanic["Age"] > 35]
In [13]: above_35.head()
Out[13]: 
PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
1             2         1       1  ...  71.2833   C85         C
6             7         0       1  ...  51.8625   E46         S
11           12         1       1  ...  26.5500  C103         S
13           14         0       3  ...  31.2750   NaN         S
15           16         1       2  ...  16.0000   NaN         S
[5 rows x 12 columns]
  • 直接输出逻辑表达式,我们可以得到一个和原先数据集同行数的数据表,其结果是对数据集的每一行都进行逻辑判断,返回该行的判断结果是Ture或False
In [14]: titanic["Age"] > 35
Out[14]: 
0      False
1       True
2      False
3      False
4      False
...  
886    False
887    False
888    False
889    False
890    False
Name: Age, Length: 891, dtype: bool

  1. 除了简单的逻辑表达式,还可以对每一行的数据进行数据范围的过滤。同样,用isin()对数据表进行过滤,返回的也是一个对数据表每一行进行isin判断的Ture或False的数据表
In [16]: class_23 = titanic[titanic["Pclass"].isin([2, 3])]

In [17]: class_23.head()
Out[17]: 
PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
0            1         0       3  ...   7.2500   NaN         S
2            3         1       3  ...   7.9250   NaN         S
4            5         0       3  ...   8.0500   NaN         S
5            6         0       3  ...   8.4583   NaN         Q
7            8         0       3  ...  21.0750   NaN         S

[5 rows x 12 columns]
  • 上面的写法更为简洁,用逻辑表达式与或非也可以表示用样的意思,只不过不能概括,有点穷举法的意思
In [18]: class_23 = titanic[(titanic["Pclass"] == 2) | (titanic["Pclass"] == 3)]

In [19]: class_23.head()
Out[19]: 
PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
0            1         0       3  ...   7.2500   NaN         S
2            3         1       3  ...   7.9250   NaN         S
4            5         0       3  ...   8.0500   NaN         S
5            6         0       3  ...   8.4583   NaN         Q
7            8         0       3  ...  21.0750   NaN         S

[5 rows x 12 columns]
  • 此外,若有多个条件语句时,每一个条件语句都要用()括起来。而且,不能使用andor来表示与或,而是要使用&|来表示与或。
  1. 可以对某些列的值进行非空过滤,换句话说就是只想得到已知值的数据。对数据表使用notna()函数会为每一行返回一个布尔值,其会结合方括号中的指定内容来过滤数据表的非空数据。
In [20]: age_no_na = titanic[titanic["Age"].notna()]

In [21]: age_no_na.head()
Out[21]: 
   PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
0            1         0       3  ...   7.2500   NaN         S
1            2         1       1  ...  71.2833   C85         C
2            3         1       3  ...   7.9250   NaN         S
3            4         1       1  ...  53.1000  C123         S
4            5         0       3  ...   8.0500   NaN         S

[5 rows x 12 columns]
  • 可能显示的依旧是数据表的前五行,我们可能看出不来是否变化,此时可以使用shape属性检查数据表的尺寸是否发生变化。
In [22]: age_no_na.shape
Out[22]: (714, 12)

3. 在数据表中选择出特定的行和列

image.png

  1. 前面提到的两种方法,都只能指定行或者列的条件,但其实我们还可以同时对这两者同时控制,此时进不能使用之前简单的方括号了,此时需要新的运算符loc\iloc。需要在方括号前加上loc\iloc运算符,在方括号中,逗号前是我们选择的行,逗号后是我们选择的列

In this case, a subset of both rows and columns is made in one go and just using selection brackets [] is not sufficient anymore.

In [23]: adult_names = titanic.loc[titanic["Age"] > 35, "Name"]

In [24]: adult_names.head()
Out[24]: 
1     Cumings, Mrs. John Bradley (Florence Briggs Th...
6                               McCarthy, Mr. Timothy J
11                             Bonnell, Miss. Elizabeth
13                          Andersson, Mr. Anders Johan
15                     Hewlett, Mrs. (Mary D Kingcome) 
Name: Name, dtype: object
  • 对于逗号前后的内容,可以使用很多形式,只要最终结果是对行的布尔值判定以及对列的选择即可。还可以使用:冒号,表示对行或者列从头到尾的选择。

For both the part before and after the comma, you can use a single label, a list of labels, a slice of labels, a conditional expression or a colon. Using a colon specifies you want to select all rows or columns.

  1. 我们可以对表格中的行和列的数值表示范围进行指定,此时需要使用到iloc运算符。与numpy中的索引切片类似,也可以用冒号来表示序列的切片
In [25]: titanic.iloc[9:25, 2:5]
Out[25]: 
    Pclass                                 Name     Sex
9        2  Nasser, Mrs. Nicholas (Adele Achem)  female
10       3      Sandstrom, Miss. Marguerite Rut  female
11       1             Bonnell, Miss. Elizabeth  female
12       3       Saundercock, Mr. William Henry    male
13       3          Andersson, Mr. Anders Johan    male
..     ...                                  ...     ...
20       2                 Fynney, Mr. Joseph J    male
21       2                Beesley, Mr. Lawrence    male
22       3          McGowan, Miss. Anna "Annie"  female
23       1         Sloper, Mr. William Thompson    male
24       3        Palsson, Miss. Torborg Danira  female

[16 rows x 3 columns]
  1. 两个运算符之间的区别,loc是对数据表的行名和列名进行指定的,而iloc是对数据表的中的特定位置坐标进行指定

Select specific rows and/or columns using loc when using the row and column names.
Select specific rows and/or columns using iloc when using the positions in the table.

  1. 可以使用这两个运算符对数据表进行条件筛选后,然后对被选择出来的行和列进行单独赋值。看我们是要用行列名或者用数据表中的数值索引来筛选,从而分别使用loc或者iloc
In [26]: titanic.iloc[0:3, 3] = "anonymous"

In [27]: titanic.head()
Out[27]: 
   PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
0            1         0       3  ...   7.2500   NaN         S
1            2         1       1  ...  71.2833   C85         C
2            3         1       3  ...   7.9250   NaN         S
3            4         1       1  ...  53.1000  C123         S
4            5         0       3  ...   8.0500   NaN         S

[5 rows x 12 columns]

4. 在数据表中从现有列中生成新的列

例题数据(空气质量数据)

In [2]: air_quality = pd.read_csv("data/air_quality_no2.csv", index_col=0, parse_dates=True)

In [3]: air_quality.head()
Out[3]: 
                     station_antwerp  station_paris  station_london
datetime                                                           
2019-05-07 02:00:00              NaN            NaN            23.0
2019-05-07 03:00:00             50.5           25.0            19.0
2019-05-07 04:00:00             45.0           27.7            19.0
2019-05-07 05:00:00              NaN           50.4            16.0
2019-05-07 06:00:00              NaN           61.9             NaN

image.png

  1. 直接在表达式等号左侧,数据表的方括号中写出想要新添加的列,然后在等号右侧写对原先的列的算术运算或逻辑运算,该运算会对给定列中的所有值都进行运算
In [4]: air_quality["london_mg_per_cubic"] = air_quality["station_london"] * 1.882

In [5]: air_quality.head()
Out[5]: 
                     station_antwerp  ...  london_mg_per_cubic
datetime                              ...                     
2019-05-07 02:00:00              NaN  ...               43.286
2019-05-07 03:00:00             50.5  ...               35.758
2019-05-07 04:00:00             45.0  ...               35.758
2019-05-07 05:00:00              NaN  ...               30.112
2019-05-07 06:00:00              NaN  ...                  NaN

[5 rows x 4 columns]

Also other mathematical operators (+,-, *, /,…) or logical operators (<, >, ==,…) work element-wise.

  • 想要进行更复杂的运算,就需要用到数据表的 apply() 方法了
  1. 除了手动创建新的列,我们还可以对已存在的列进行重命名.rename()函数可用于行标签和列标签。提供一个字典,其中包含当前名称的键和新名称的值以更新相应的名称。
In [8]: air_quality_renamed = air_quality.rename(
    columns={
        "station_antwerp": "BETR801",
        "station_paris": "FR04014",
        "station_london": "London Westminster",
    }
)

In [9]: air_quality_renamed.head()
Out[9]: 
                     BETR801  FR04014  ...  london_mg_per_cubic  ratio_paris_antwerp
datetime                               ...                                          
2019-05-07 02:00:00      NaN      NaN  ...               43.286                  NaN
2019-05-07 03:00:00     50.5     25.0  ...               35.758             0.495050
2019-05-07 04:00:00     45.0     27.7  ...               35.758             0.615556
2019-05-07 05:00:00      NaN     50.4  ...               30.112                  NaN
2019-05-07 06:00:00      NaN     61.9  ...                  NaN                  NaN

[5 rows x 5 columns]

对数据表的聚合统计

  1. 我们可以直接对单列数据进行平均值的统计,但要是统计多列的平均值呢?首先我们需要对多个目标列用列表[]括起来进行聚合,和之前提到的在数据表中选择多个列操作一样,然后再对这多个列进行统计平均值操作。
In [5]: titanic[["Age", "Fare"]].median()
Out[5]: 
Age     28.0000
Fare    14.4542
dtype: float64
  1. 同样对于之前的describe()数据表数据概述,也可以应用到多个列上
In [6]: titanic[["Age", "Fare"]].describe()
Out[6]: 
              Age        Fare
count  714.000000  891.000000
mean    29.699118   32.204208
std     14.526497   49.693429
min      0.420000    0.000000
25%     20.125000    7.910400
50%     28.000000   14.454200
75%     38.000000   31.000000
max     80.000000  512.329200
  • 但是我们也可以自定义想要显示的统计信息的特定组合,而不是像describe()中预定义好的统计信息,使用DataFrame.agg()在参数列表内填入字典,字典中的键值对是目标列以及想要显示的统计信息(有多个就用列表表示 )
In [7]: titanic.agg(
   ...:     {
   ...:         "Age": ["min", "max", "median", "skew"],
   ...:         "Fare": ["min", "max", "median", "mean"],
   ...:     }
   ...: )
   ...: 
Out[7]: 
              Age        Fare
min      0.420000    0.000000
max     80.000000  512.329200
median  28.000000   14.454200
skew     0.389108         NaN
mean          NaN   32.204208

对数据表的分组统计

  1. 可以对统计信息进行类别分组

image.png
和数据库条件查询操作类似,这边做的信息统计是列中的每一个类别分组进行的,使用groupby()可以对指定列的每一个类别进行分组,然后对数据表的统计操作就会单独作用于每一个分组,最后这些结果会被合成一个数据表

the groupby() method is applied on the Sex column to make a group per category.

In [8]: titanic[["Sex", "Age"]].groupby("Sex").mean()
Out[8]: 
              Age
Sex              
female  27.915709
male    30.726645
  • 只是单独对数据表进行分类没有什么意义,分组后要跟上对数据的操作,这样才能实现更灵活的运算。

  • 上面的例子是事先选择了两列,若没有提前选择列,那么就会默认全部列, 这边利用numeric_only =True指定平均值计算只应用于数值类数据

In [9]: titanic.groupby("Sex").mean(numeric_only=True)
Out[9]: 
        PassengerId  Survived    Pclass  ...     SibSp     Parch       Fare
Sex                                      ...                               
female   431.028662  0.742038  2.159236  ...  0.694268  0.649682  44.479818
male     454.147314  0.188908  2.389948  ...  0.429809  0.235702  25.523893

[2 rows x 7 columns]
  • 上面的例子是先选择列后分组,但我们也可以先分组再选择

image.png

In [10]: titanic.groupby("Sex")["Age"].mean()
Out[10]: 
Sex
female    27.915709
male      30.726645
Name: Age, dtype: float64
  1. 不止可以对一个列进行分组,也可以对多个列进行分类,将多个列用列表存储起来就行了。这样分组的结果就是所有类别的排列组合(树形),然后类别的排列顺序依靠分组函数参数列表中列名的先后顺序
In [11]: titanic.groupby(["Sex", "Pclass"])["Fare"].mean()
Out[11]: 
Sex     Pclass
female  1         106.125798
        2          21.970121
        3          16.118810
male    1          67.226127
        2          19.741782
        3          12.661633
Name: Fare, dtype: float64
  1. 可以按分组计算记录数

image.png
如想要查看每个舱位等级的乘客人数是多少,value_counts()方法计算列中每个类别的记录数。在该方法中,可以利用该方法的参数dropna来包含或者排除缺失值。

In [12]: titanic["Pclass"].value_counts()
Out[12]: 
3    491
1    216
2    184
Name: Pclass, dtype: int64
  • 利用上面提到的分组操作也可以实现计数功能,只不过功能没有value_count()来得灵活方便

Both size and count can be used in combination with groupby. Whereas size includes NaN values and just provides the number of rows (size of the table), count excludes the missing values. In the value_counts method, use the dropna argument to include or exclude the NaN values.

In [13]: titanic.groupby("Pclass")["Pclass"].count()
Out[13]: 
Pclass
1    216
2    184
3    491
Name: Pclass, dtype: int64

重塑表格布局

对表格进行排序

可以使用sort_values(),数据表中的行会根据指定的列进行排序,其中by=是排序的依据,默认是升序排序

In [6]: titanic.sort_values(by="Age").head()
Out[6]: 
     PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
803          804         1       3  ...   8.5167   NaN         C
755          756         1       2  ...  14.5000   NaN         S
644          645         1       3  ...  19.2583   NaN         C
469          470         1       3  ...  19.2583   NaN         C
78            79         1       2  ...  29.0000   NaN         S

[5 rows x 12 columns]
  • 可以同时对多个列进行排序,同时还可以选择降序排序,对参数进行调整ascending=False
In [7]: titanic.sort_values(by=['Pclass', 'Age'], ascending=False).head()
Out[7]: 
     PassengerId  Survived  Pclass  ...    Fare Cabin  Embarked
851          852         0       3  ...  7.7750   NaN         S
116          117         0       3  ...  7.7500   NaN         Q
280          281         0       3  ...  7.7500   NaN         Q
483          484         1       3  ...  9.5875   NaN         S
326          327         0       3  ...  6.2375   NaN         S

[5 rows x 12 columns]

合并多个表的数据

1. 按行或列连接表

image.png

  1. 利用concat()函数沿其中一个轴(按行或按列)执行多个表的串联操作,也就是说我们进左右合并或者上下合并。数据表有两个轴,axis=0代表垂直方向合并行,axis=1代表水平方向上合并列。串联默认是沿着axis=0进行的。
In [8]: air_quality = pd.concat([air_quality_pm25, air_quality_no2], axis=0)

In [9]: air_quality.head()
Out[9]: 
                    date.utc location parameter  value
0  2019-06-18 06:00:00+00:00  BETR801      pm25   18.0
1  2019-06-17 08:00:00+00:00  BETR801      pm25    6.5
2  2019-06-17 07:00:00+00:00  BETR801      pm25   18.5
3  2019-06-17 06:00:00+00:00  BETR801      pm25   16.0
4  2019-06-17 05:00:00+00:00  BETR801      pm25    7.5
  • 在这个例子数据当中,两个表是都各自的参数parameter可以标记数据原先所属,但不一定每一次合并的数据表中都有自己的标记。
  • 我们可以使用concat()中的函数参数keys来添加一个额外的行索引来标记不同的原始表

In this specific example, the parameter column provided by the data ensures that each of the original tables can be identified. This is not always the case. The concat function provides a convenient solution with the keys argument, adding an additional (hierarchical) row index.

In [15]: air_quality_ = pd.concat([air_quality_pm25, air_quality_no2], keys=["PM25", "NO2"])

In [16]: air_quality_.head()
Out[16]: 
                         date.utc location parameter  value
PM25 0  2019-06-18 06:00:00+00:00  BETR801      pm25   18.0
     1  2019-06-17 08:00:00+00:00  BETR801      pm25    6.5
     2  2019-06-17 07:00:00+00:00  BETR801      pm25   18.5
     3  2019-06-17 06:00:00+00:00  BETR801      pm25   16.0
     4  2019-06-17 05:00:00+00:00  BETR801      pm25    7.5

2. 通过公共列连接表

  1. 通过共同键从而将两个表连接在一起,类似数据库中的表连接概念,how=left说明是左连接方式,即参数列表中左边一个数据表中每行每列都会在新表上显示出来,on="location"就是我们指定的要连接的公共键
In [20]: air_quality = pd.merge(air_quality, stations_coord, how="left", on="location")

In [21]: air_quality.head()
Out[21]: 
                    date.utc  ... coordinates.longitude
0  2019-05-07 01:00:00+00:00  ...              -0.13193
1  2019-05-07 01:00:00+00:00  ...               2.39390
2  2019-05-07 01:00:00+00:00  ...               2.39390
3  2019-05-07 01:00:00+00:00  ...               4.43182
4  2019-05-07 01:00:00+00:00  ...               4.43182

[5 rows x 6 columns]
  1. 上面的例子是在对两个表的同名列进行来连接,但我们也可以对两个表的不同名列进行连接,在参数left_onright_on中指定即可
In [24]: air_quality = pd.merge(air_quality, air_quality_parameters,
   ....:                        how='left', left_on='parameter', right_on='id')
   ....: 

In [25]: air_quality.head()
Out[25]: 
                    date.utc  ...   name
0  2019-05-07 01:00:00+00:00  ...    NO2
1  2019-05-07 01:00:00+00:00  ...    NO2
2  2019-05-07 01:00:00+00:00  ...    NO2
3  2019-05-07 01:00:00+00:00  ...  PM2.5
4  2019-05-07 01:00:00+00:00  ...    NO2

[5 rows x 9 columns]
  • 除了左连接外,pandas还支持内连接、外连接和全连接等

pandas supports also inner, outer, and right joins. More information on join/merge of tables is provided in the user guide section on database style merging of tables. Or have a look at the comparison with SQL page.

对时间序列数据进行处理

  1. 有时我们的日期是用字符串存储的,pandas中提供了to_datatime方法可以将标准时间戳转换为Timestamp对象,这样日期就由字符串变换为数字了,转换后的数据类型为pandas.Timestamp.
In [7]: air_quality["datetime"] = pd.to_datetime(air_quality["datetime"])

In [8]: air_quality["datetime"]
Out[8]: 
0      2019-06-21 00:00:00+00:00
1      2019-06-20 23:00:00+00:00
2      2019-06-20 22:00:00+00:00
3      2019-06-20 21:00:00+00:00
4      2019-06-20 20:00:00+00:00
                  ...           
2063   2019-05-07 06:00:00+00:00
2064   2019-05-07 04:00:00+00:00
2065   2019-05-07 03:00:00+00:00
2066   2019-05-07 02:00:00+00:00
2067   2019-05-07 01:00:00+00:00
Name: datetime, Length: 2068, dtype: datetime64[ns, UTC]
  • 同样在很多文件时,里面的日期数据也是用字符串存储的,在导入文件时可以使用参数parse_dates将其转换为日期对象
pd.read_csv("../data/air_quality_no2_long.csv", parse_dates=["datetime"])
  1. 有了日期信息后,我们就可以在pandas.Timestamp中使用一些方法来对日期进行操作了
In [9]: air_quality["datetime"].min(), air_quality["datetime"].max()
Out[9]: 
(Timestamp('2019-05-07 01:00:00+0000', tz='UTC'),
 Timestamp('2019-06-21 00:00:00+0000', tz='UTC'))
  • 甚至我们可以得出数据表中的时间跨度,用最大时间减去最小时间即可
In [10]: air_quality["datetime"].max() - air_quality["datetime"].min()
Out[10]: Timedelta('44 days 23:00:00')
  1. 可以从Timestamp对象中,取出很多与时间相关的属性,例如year, weekofyear, quarter等属性,通过 .dt访问器就可以从时间戳对象中去这些属性,.dt访问器返回的是一个Series,
     In [11]: air_quality["month"] = air_quality["datetime"].dt.month

In [12]: air_quality.head()
Out[12]: 
    city country                  datetime  ... value   unit  month
0  Paris      FR 2019-06-21 00:00:00+00:00  ...  20.0  µg/6
1  Paris      FR 2019-06-20 23:00:00+00:00  ...  21.8  µg/6
2  Paris      FR 2019-06-20 22:00:00+00:00  ...  26.5  µg/6
3  Paris      FR 2019-06-20 21:00:00+00:00  ...  24.9  µg/6
4  Paris      FR 2019-06-20 20:00:00+00:00  ...  21.4  µg/6

[5 rows x 8 columns]

转换时间序列的频率

  1. 这个操作类似于之前的分组操作,也是需要配合聚合函数一起操作才行,如我们想要获取每个月日期的最大值,也就是最后一天月尾,就可以使用reshape("M"),除了这个我们还有其他类似的概述名可供选择 offset aliases overview table
In [22]: monthly_max = no_2.resample("M").max()

In [23]: monthly_max
Out[23]: 
location                   BETR801  FR04014  London Westminster
datetime                                                       
2019-05-31 00:00:00+00:00     74.5     97.0                97.0
2019-06-30 00:00:00+00:00     52.5     84.7                52.0

对文本数据的操作

pandas中提供了str访问器,使用该访问器,可以让我们对字符串数据进行专门的字符串操作。

1. 将字符串转为小写

将所有字符串都设为小写

In [4]: titanic["Name"].str.lower()
Out[4]: 
0                                braund, mr. owen harris
1      cumings, mrs. john bradley (florence briggs th...
2                                 heikkinen, miss. laina
3           futrelle, mrs. jacques heath (lily may peel)
4                               allen, mr. william henry
                             ...                        
886                                montvila, rev. juozas
887                         graham, miss. margaret edith
888             johnston, miss. catherine helen "carrie"
889                                behr, mr. karl howell
890                                  dooley, mr. patrick
Name: Name, Length: 891, dtype: object

2. 分隔字符串

指定分隔符将原本的字符串分隔开,分隔后的字符用列表存储起来,返回的是被分隔元素列表

In [5]: titanic["Name"].str.split(",")
Out[5]: 
0                             [Braund,  Mr. Owen Harris]
1      [Cumings,  Mrs. John Bradley (Florence Briggs ...
2                              [Heikkinen,  Miss. Laina]
3        [Futrelle,  Mrs. Jacques Heath (Lily May Peel)]
4                            [Allen,  Mr. William Henry]
                             ...                        
886                             [Montvila,  Rev. Juozas]
887                      [Graham,  Miss. Margaret Edith]
888          [Johnston,  Miss. Catherine Helen "Carrie"]
889                             [Behr,  Mr. Karl Howell]
890                               [Dooley,  Mr. Patrick]
Name: Name, Length: 891, dtype: object
  • 此外,我们还可以对分隔后的部分进行选择,Series.str.get()即可对字符串进行选择,这边将分隔操作和部分选择操作组合了在一起
In [6]: titanic["Surname"] = titanic["Name"].str.split(",").str.get(0)
# 选择了第一部分
In [7]: titanic["Surname"]
Out[7]: 
0         Braund
1        Cumings
2      Heikkinen
3       Futrelle
4          Allen
         ...    
886     Montvila
887       Graham
888     Johnston
889         Behr
890       Dooley
Name: Surname, Length: 891, dtype: object

3. 查找含有特定文本的行

查找数据表中符合给定名称的项,使用字符串访问器的contains()方法,这个方法可以对给定表的所有行进行逻辑判定,会给每一行数据都返回一个布尔值。该方法支持正则表达式,可以进行更强大的文本提取方法。

In [8]: titanic["Name"].str.contains("Countess")
Out[8]: 
0      False
1      False
2      False
3      False
4      False
       ...  
886    False
887    False
888    False
889    False
890    False
Name: Name, Length: 891, dtype: bool
  • 有了这个布尔值,我们就可以对给定数据表进行条件查询。只有被筛选为True的行才会被选择出来。
In [9]: titanic[titanic["Name"].str.contains("Countess")]
Out[9]: 
     PassengerId  Survived  Pclass  ... Cabin Embarked  Surname
759          760         1       1  ...   B77        S   Rothes

[1 rows x 13 columns]

4. 计算字符串长度

使用访问其中的len()就能得到被访问对象的字符串长度

In [10]: titanic["Name"].str.len()
Out[10]: 
0      23
1      51
2      22
3      44
4      24
       ..
886    21
887    28
888    40
889    21
890    19
Name: Name, Length: 891, dtype: int64

除了得到字串的长度外,我们还可以找到最长字符所在行的索引值,使用访问器中的方法idxmax(),可以返回给定的数据列表中最大值所在行的索引值

In [11]: titanic["Name"].str.len().idxmax()
Out[11]: 307

5。替换字符

使用replace(),将旧字符和新字符用键值对的方式存储在字典中,然后将字典存放在方法的参数列表中,

In [13]: titanic["Sex_short"] = titanic["Sex"].replace({"male": "M", "female": "F"})

In [14]: titanic["Sex_short"]
Out[14]: 
0      M
1      F
2      F
3      F
4      M
      ..
886    M
887    F
888    F
889    M
890    M
Name: Sex_short, Length: 891, dtype: object
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值