在后台回复【阅读书籍】

即可获取python相关电子书~

Hi,我是山月。

今天给大家带来一个强大的朋友:pandas。如果你有许多数据分析任务的话,那你一定不能错过它。

由于它的内容比较多,因此会分成几部分来讲解,今天只来讲解下入门教程,有兴趣的话可以多加关注哦~

官网:https://pandas.pydata.org/

如果需要pdf版官方文档的话,可以在后台回复【pandas文档】来获取哦~

安装:pip install pandas

导入pandas:

import pandas as pd # 一般命名为pd

查看 pandas 版本:

import pandas as pd
pd_version = pd.__version__  # 查看版本
print(pd_version)   # 1.1.5

01

DataFrame和Series

DataFrame和Series是pandas非常基础也是非常重要的两个概念。

1、DataFrame

要将数据存储在表中,需要创建一个 DataFrame,它的数据是一个值为列表的字典。

字典的键用作列标题,每个列表中的值将用作 DataFrame 的列。

DataFrame 是一种二维数据结构,可以在列中存储不同类型的数据(包括字符、整数、浮点值、分类数据等)。

如:

import pandas as pd # 一般命名为pddf = pd.DataFrame({"Name": ["Braund, Mr. Owen Harris","Allen, Mr. William Henry","Bonnell, Miss. Elizabeth",],"Age": [22, 35, 58],"Sex": ["male", "male", "female"],}
)print(df)'''Name  Age     Sex
0   Braund, Mr. Owen Harris   22    male
1  Allen, Mr. William Henry   35    male
2  Bonnell, Miss. Elizabeth   58  female'''

2、Series

DataFrame 中的每一列都是一个Series。因此Pandas里选择DataFrame 的单列时,结果是Series。

如果你想要选择单列,可以在方括号 [] 里添加要选择列的列标签。

print(df["Age"])'''
0    22
1    35
2    58
Name: Age, dtype: int64
'''

如果想从头开始创建Series:

import pandas as pd # 一般命名为pdages = pd.Series([22, 35, 58], name="Age")
print(ages)'''
0    22
1    35
2    58
Name: Age, dtype: int64
'''

Series没有列标签,因为它只是 DataFrame 的一列,但Series有行标签。

3、使用 DataFrame 或 Series

pandas 提供了很多功能,每个功能都是可以应用于 DataFrame 或 Series 的方法(由于方法是函数,所以不要忘记使用括号 )。

其中max() 方法可以求出一列数据里的最大值。

比如在 DataFrame 上求出最大年龄:

import pandas as pd # 一般命名为pddf = pd.DataFrame({"Name": ["Braund, Mr. Owen Harris","Allen, Mr. William Henry","Bonnell, Miss. Elizabeth",],"Age": [22, 35, 58],"Sex": ["male", "male", "female"],}
)print(df["Age"].max())      # 58

在Series上求出最大年龄:

import pandas as pd # 一般命名为pdages = pd.Series([22, 35, 58], name="Age")
print(ages.max())   #58

02

读取和写入表格数据

1、读取

pandas 提供了 read_csv() 函数来将存储为 csv 文件的数据读取到 pandas DataFrame 中。

pandas 支持许多不同的文件格式或开箱即用的数据源(csv、excel、sql、json、parquet 等),每一个都带有前缀 read_*。

如:

titanic = pd.read_csv("titanic.csv")
titanic = pd.read_excel("titanic.xlsx", sheet_name="passengers")

要查看 DataFrame 的前 N 行,可以使用 head() 方法,并将所需的行数(如 2)作为参数:

titanic.head(2)

可以通过请求dtypes 属性来检查 pandas 如何解释每列的数据类型:

titanic.dtypes

数据类型有整数(int64)、浮点数(float64)和字符串(object)。

2、存储

to_* 方法可以用于存储数据。

to_excel() 方法将数据存储为 excel 文件:

titanic.to_excel("titanic.xlsx", sheet_name="passengers", index=False) #index=False 行索引标签不会保存在电子表格中

方法 info() 提供 DataFrame 的技术信息,可以让我们更详细地解释输出:

titanic.info()

3、实例

import pandas as pd # 一般命名为pddf = pd.DataFrame({"Name": ["Braund, Mr. Owen Harris","Allen, Mr. William Henry","Bonnell, Miss. Elizabeth",],"Age": [22, 35, 58],"Sex": ["male", "male", "female"],}
)df.to_excel("titanic.xlsx", sheet_name="passengers", index=False) #保存成exceltitanic = pd.read_excel("titanic.xlsx", sheet_name="passengers") # 读取excel
print(titanic.head(2)) #查看表格前两行数据
print('-------')
print(titanic.dtypes) #查看每列的数据类型
print('-------')
print(titanic.info()) #查看DataFrame 的技术信息'''Name  Age   Sex
0   Braund, Mr. Owen Harris   22  male
1  Allen, Mr. William Henry   35  male
-------
Name    object
Age      int64
Sex     object
dtype: object
-------
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 3 columns):      #   Column  Non-Null Count  Dtype
---  ------  --------------  -----   0   Name    3 non-null      object1   Age     3 non-null      int642   Sex     3 non-null      object
dtypes: int64(1), object(2)
memory usage: 200.0+ bytes
None
'''

03

选择 DataFrame 的子集

1、从 DataFrame 中选择特定列

要选择单个列,可以使用方括号 [] ,方括号里是要选择列的列名:

import pandas as pd # 一般命名为pddf = pd.DataFrame({"Name": ["Braund, Mr. Owen Harris","Allen, Mr. William Henry","Bonnell, Miss. Elizabeth",],"Age": [22, 35, 58],"Sex": ["male", "male", "female"],}
)ages = df["Age"]
print(ages.head())'''
0    22
1    35
2    58
Name: Age, dtype: int64
'''

DataFrame 中的每一列都是一个series,因此选择单个列时,返回的对象是Series。

我们可以通过检查输出的类型来验证这一点:

print(type(df["Age"])) # <class 'pandas.core.series.Series'>

DataFrame.shape 是Series 和 DataFrame 的一个属性(属性不要使用括号),包含行数和列数:(nrows, ncolumns)。

其中series是一维的,只会返回行数。

print(df.shape) # (3,3)
print(df["Age"].shape) # (3,)

如果要选择多个列,方括号里是要选择列的列名列表:

age_sex = df[["Age", "Sex"]]
print(age_sex.head())
'''Age     Sex
0   22    male
1   35    male
2   58  female
'''

返回的数据类型是DataFrame,DataFrame 是二维的,具有行和列维度:

print(type(df[["Age", "Sex"]])) # <class 'pandas.core.frame.DataFrame'>
print(df[["Age", "Sex"]].shape) # (3, 2)

2、过滤 DataFrame 中的特定行

要根据条件表达式选择行,需要在选择方括号 [] 内使用条件。

条件表达式的输出(>,但也可以使用 ==、!=、<、<=、...)实际上是series的布尔值(True 或 False),其行数与原始 DataFrame 相同。

这样的一系列布尔值可用于过滤 DataFrame,方法是将其放在方括号 [] 里,然后选择值为 True 的行。

import pandas as pd # 一般命名为pddf = pd.DataFrame({"Name": ["Braund, Mr. Owen Harris","Allen, Mr. William Henry","Bonnell, Miss. Elizabeth",],"Age": [22, 35, 58],"Sex": ["male", "male", "female"],}
)above_35 = df[df["Age"] > 35]   # Age 列的值大于 35 的行
print(above_35.head())'''Name  Age     Sex
2  Bonnell, Miss. Elizabeth   58  female
'''

我们知道原始的DataFrame 由 3 行组成的,现在我们通过above_35 的 shape 属性来看看满足条件的行数:

above_35 = df[df["Age"] > 35]   #年龄大于35的
print(df.shape)         # (3, 3)
print(above_35.shape) #  (1, 3)

与条件表达式类似,isin()条件函数为所提供列表中的每一行返回一个True:

import pandas as pd # 一般命名为pddf = pd.DataFrame({"Name": ["Braund, Mr. Owen Harris","Allen, Mr. William Henry","Bonnell, Miss. Elizabeth",],"Age": [22, 35, 58],"Sex": ["male", "male", "female"],}
)Age_22_58 = df[df["Age"].isin([22, 58])]
print(Age_22_58.head())
'''Name  Age     Sex
0   Braund, Mr. Owen Harris   22    male
2  Bonnell, Miss. Elizabeth   58  female
'''#等价于
Age_22_58 = df[(df["Age"] == 22) | (df["Age"] == 58)] #两个条件语句用 | (or 运算符)连接
print(Age_22_58.head())

注意:组合多个条件语句时,每个条件必须用括号 () 括起来,然后用运算符连接。

但不能使用 or/and ,而是需要使用  | (or 运算符)和 &(and 运算符 )。

notna() 条件函数为值不是 Null 值的每一行返回 True:

age_no_na = df[df["Age"].notna()]

3、从 DataFrame 中选择特定的行和列

在这种情况下,一次性生成行和列的子集,仅使用方括号 [] 已经不够了,需要在方括号 [] 前面加上loc/iloc 运算符。

使用 loc/iloc 时,逗号之前的部分是想要的行,逗号之后的部分是要选择的列。

如:

import pandas as pd # 一般命名为pddf = pd.DataFrame({"Name": ["Braund, Mr. Owen Harris","Allen, Mr. William Henry","Bonnell, Miss. Elizabeth",],"Age": [22, 35, 58],"Sex": ["male", "male", "female"],}
)adult_names = df.loc[df["Age"] > 35, "Name"] # 年龄大于35岁对应的的名字
print(adult_names.head())
'''
2    Bonnell, Miss. Elizabeth
Name: Name, dtype: object
'''print(df.iloc[1:3, 1:3]) #第2到3行和第2列到3列数据
'''Age     Sex
1   35    male
2   58  female
'''

使用 loc 或 iloc 选择特定行和/或列时,可以为所选数据分配新值。

例如,将【新值】分配给第3列的前 2 个元素:

df.iloc[0:2, 2] = "新值"    # 将【新值】分配给第3列的前 2 个元素
print(df.head())'''Name  Age     Sex
0   Braund, Mr. Owen Harris   22      新值
1  Allen, Mr. William Henry   35      新值
2  Bonnell, Miss. Elizabeth   58  female
'''

04

图表

需要导入matplotlib:

import matplotlib.pyplot as plt

数据.csv内容:

创建图表:

import pandas as pd
import matplotlib.pyplot as pltair_quality = pd.read_csv("数据.csv", index_col=0, parse_dates=True) #使用 read_csv 函数的 index_col 和 parse_dates 参数将第1列定义为DataFrame 的索引,并将列中的日期转换为 Timestamp 对象。
air_quality.plot() # pandas 默认为带有数字数据的每一列创建一个线图plt.show()  # 显示图表

效果:

如果想绘制特定列的图表,要结合使用子集数据的选择方法和 plot() 方法:

import pandas as pd
import matplotlib.pyplot as pltair_quality = pd.read_csv("数据.csv", index_col=0, parse_dates=True)
air_quality["station_paris"].plot() #绘制特定列plt.show()  # 显示图表

效果:

可绘制的图表类型:

import pandas as pd
air_quality = pd.read_csv("数据.csv", index_col=0, parse_dates=True)
for method_name in dir(air_quality.plot):if not method_name.startswith("_"):print(method_name)'''
area
bar
barh
box
density
hexbin
hist
kde
line
pie
scatter
'''

如绘制面积图:

import pandas as pd
import matplotlib.pyplot as pltair_quality = pd.read_csv("数据.csv", index_col=0, parse_dates=True)
axs = air_quality.plot.area(figsize=(12, 4), subplots=True)plt.show()  # 显示图表

效果:

进一步自定义、扩展或保存结果图:

import pandas as pd
import matplotlib.pyplot as pltair_quality = pd.read_csv("数据.csv", index_col=0, parse_dates=True)fig, axs = plt.subplots(figsize=(12, 4))
air_quality.plot.area(ax=axs)
axs.set_ylabel("NO$_2$ concentration")fig.savefig("实例.png") # 保存图表

效果:

05

从现有列派生新列

要创建新列,需要在赋值左侧使用带有新列名称的 [] 括号:

import pandas as pddf = pd.DataFrame({"Name": ["Braund, Mr. Owen Harris","Allen, Mr. William Henry","Bonnell, Miss. Elizabeth",],"Age": [22, 35, 58],"Sex": ["male", "male", "female"],}
)df["Age_10year_later"] = df["Age"] + 10 # 新添一列
print(df.head())'''Name  Age     Sex  Age_10year_later
0   Braund, Mr. Owen Harris   22    male                32
1  Allen, Mr. William Henry   35    male                45
2  Bonnell, Miss. Elizabeth   58  female                68
'''

注意:这里的计算是由 element_wise 完成的。也就是说是把所有的年龄值以元素为单位一次性加上10 ,而不需要使用循环来迭代每一行。

常用的数学运算符(+、-、*、/)或逻辑运算符(<、>、=、...)都可以按元素工作。

rename() 函数可用于行标签和列标签。它可以通过字典来更新标签名称,其中字典的键是当前标签名称,值是要更新的标签名称。

df_renamed = df.rename(columns={"Name": "Name_renamed","Age": "Age_renamed","Sex": "Sex_renamed",}
)print(df_renamed.head())
'''Name_renamed  Age_renamed Sex_renamed
0   Braund, Mr. Owen Harris           22        male
1  Allen, Mr. William Henry           35        male
2  Bonnell, Miss. Elizabeth           58      female
'''

rename() 函数的参数也可以是函数。例如,可以使用函数将列名转换为小写字母:

df_renamed = df.rename(columns=str.lower)
print(df_renamed.head())
'''name  age     sex
0   Braund, Mr. Owen Harris   22    male
1  Allen, Mr. William Henry   35    male
2  Bonnell, Miss. Elizabeth   58  female
'''

06

计算汇总统计

1、汇总统计信息

计算平均值和中位数:

import pandas as pddf = pd.DataFrame({"Name": ["Braund, Mr. Owen Harris","Allen, Mr. William Henry","Bonnell, Miss. Elizabeth",],"Age": [22, 35, 58],"Sex": ["male", "male", "female"],"Fare": [7.25, 71.28, 53.1],}
)
print("平均年龄:")
print(df["Age"].mean()) #
print("年龄和票价的中位数是:")
print(df[["Age", "Fare"]].median())
'''
平均年龄:
38.333333333333336
年龄和票价的中位数是:
Age     35.0
Fare    53.1
dtype: float64
'''

describe()函数可以计算汇总统计信息:

print(df[["Age", "Fare"]].describe())
'''Age       Fare
count   3.000000   3.000000
mean   38.333333  43.876667
std    18.230012  32.996403
min    22.000000   7.250000
25%    28.500000  30.175000
50%    35.000000  53.100000
75%    46.500000  62.190000
max    58.000000  71.280000
'''

DataFrame.agg()方法可以为给定的列定义汇总统计信息的特定组合,而不是使用预定义的统计信息:

statistics_defined = df.agg({"Age": ["min", "max", "median", "skew"],"Fare": ["min", "max", "median", "mean"],}
)print(statistics_defined)
'''Age       Fare
max     58.000000  71.280000
mean          NaN  43.876667
median  35.000000  53.100000
min     22.000000   7.250000
skew     0.795309        NaN
'''

2、汇总按类别分组的统计信息

为列中的每个类别(例如性别列中的男性/女性)计算给定的统计数据(例如平均年龄)是一种常见模式。

groupby 方法用于支持这种类型的操作,更一般地说,这适合分组-应用-组合模式:

  • 将数据分组

  • 将函数单独应用于每个组

  • 将结果组合成数据结构

应用和组合步骤通常在 pandas 中一起完成。

实例:

import pandas as pddf = pd.DataFrame({"Name": ["Braund, Mr. Owen Harris","Allen, Mr. William Henry","Bonnell, Miss. Elizabeth",],"Age": [22, 35, 58],"Sex": ["male", "male", "female"],"Fare": [7.25, 71.28, 53.1],}
)
print(df[["Sex", "Age"]].groupby("Sex").mean()) # 分别计算男性and女性的平均年龄
'''Age
Sex
female  58.0
male    28.5
'''print(df.groupby("Sex").mean()) #如果没有明确,则将mean方法应用于包含数字列的每一列
'''Age    Fare
Sex
female  58.0  53.100
male    28.5  39.265
'''print(df.groupby("Sex")["Age"].mean()) # 每个性别的平均年龄
'''
Sex
female    58.0
male      28.5
Name: Age, dtype: float64
'''print(df.groupby(["Sex", "Age"])["Fare"].mean()) #每个性别和年龄组合的平均票价
'''
Sex     Age
female  58     53.10
male    22      7.25      35     71.28
Name: Fare, dtype: float64
'''

3、按类别计算记录数

value_counts() 方法可以计算列中每个类别的记录数:

import pandas as pddf = pd.DataFrame({"Name": ["Braund, Mr. Owen Harris","Allen, Mr. William Henry","Bonnell, Miss. Elizabeth",],"Age": [22, 35, 58],"Sex": ["male", "male", "female"],"Fare": [7.25, 71.28, 53.1],}
)
print(df["Sex"].value_counts()) # 男女的人数分别是多少
'''
male      2
female    1
Name: Sex, dtype: int64
'''

该函数是一种快捷方式,因为它实际上是一个 groupby 操作,结合了每个组内记录数的计数:

print(df.groupby("Sex")["Sex"].count())
'''
Sex
female    1
male      2
Name: Sex, dtype: int64
'''

size 和 count 都可以与 groupby 结合使用。

区别是 size 包括 NaN 值并且只提供行数(表的大小),但 count 不包括缺失值。

在 value_counts 方法中,可以使用 dropna 参数来包含或排除 NaN 值。

07

重塑表格布局

1、排序

使用 Series.sort_values(),可以让表中的行根据定义的列进行排序,索引也将遵循行顺序:

import pandas as pddf = pd.DataFrame({"Name": ["Braund, Mr. Owen Harris","Allen, Mr. William Henry","Bonnell, Miss. Elizabeth",],"Age": [22, 35, 58],"Sex": ["male", "male", "female"],"Fare": [7.25, 71.28, 53.1],}
)print(df.sort_values(by="Fare").head()) # 根据票价进行升序排序
'''Name  Age     Sex   Fare
0   Braund, Mr. Owen Harris   22    male   7.25
2  Bonnell, Miss. Elizabeth   58  female  53.10
1  Allen, Mr. William Henry   35    male  71.28
'''print(df.sort_values(by="Fare", ascending=False).head())   # 根据票价进行降序排序
'''Name  Age     Sex   Fare
1  Allen, Mr. William Henry   35    male  71.28
2  Bonnell, Miss. Elizabeth   58  female  53.10
0   Braund, Mr. Owen Harris   22    male   7.25
'''

2、长宽表转换

简单来说,所谓长表就是列数少行数多,宽表则是列数多行数少。

1、长表转宽表(pivot)

长表转宽表用的是pivot()函数,它的主要参数:

  • index: 用于制作新框架索引的标签

  • columns: 用于制作新框架列的标签

  • values: 用于填充新框架值的值

注意:如果未定义索引参数,则使用现有索引(行标签)。

实例:

import pandas as pddata = pd.DataFrame({"date": ["04-09","04-09","04-09","04-10","04-10", "04-10","04-11","04-11","04-11"],"city": ['Antwerpen', 'Paris', 'London', 'Antwerpen', 'Paris', 'London', 'Antwerpen', 'Paris', 'London'],"value": [18.0, 6.5, 18.5, 16.0, 7.5, 12.2, 15.6, 10.8, 6.8],}
)
df = pd.DataFrame(data=data, columns=['date', 'city', 'value'])
print(df)
'''date       city  value
0  04-09  Antwerpen   18.0
1  04-09      Paris    6.5
2  04-09     London   18.5
3  04-10  Antwerpen   16.0
4  04-10      Paris    7.5
5  04-10     London   12.2
6  04-11  Antwerpen   15.6
7  04-11      Paris   10.8
8  04-11     London    6.8
'''df2 = df.pivot(index='date',columns='city',values='value')
print(df2)
'''
city   Antwerpen  London  Paris
date
04-09       18.0    18.5    6.5
04-10       16.0    12.2    7.5
04-11       15.6     6.8   10.8
'''

2、宽表转长表(melt)

宽表转长表用的是melt()函数,它的主要参数:

  • id_vars:不需要被转换的列名。

  • value_vars:需要转换的列名,如果剩下的列全部都要转换,就不用写了。

  • var_name、value_name:自定义设置对应的列名。

import pandas as pddata = pd.DataFrame({"date": ["04-09","04-09","04-09","04-10","04-10", "04-10","04-11","04-11","04-11"],"city": ['Antwerpen', 'Paris', 'London', 'Antwerpen', 'Paris', 'London', 'Antwerpen', 'Paris', 'London'],"value": [18.0, 6.5, 18.5, 16.0, 7.5, 12.2, 15.6, 10.8, 6.8],}
)
df = pd.DataFrame(data=data, columns=['date', 'city', 'value'])
df2 = df.pivot(index='date',columns='city',values='value').reset_index() # reset_index()主要用于重置索引
print(df2)
'''
city   date  Antwerpen  London  Paris
0     04-09       18.0    18.5    6.5
1     04-10       16.0    12.2    7.5
2     04-11       15.6     6.8   10.8
'''df3 = df2.melt(id_vars="date")
print(df3)
'''date       city  value
0  04-09  Antwerpen   18.0
1  04-10  Antwerpen   16.0
2  04-11  Antwerpen   15.6
3  04-09     London   18.5
4  04-10     London   12.2
5  04-11     London    6.8
6  04-09      Paris    6.5
7  04-10      Paris    7.5
8  04-11      Paris   10.8
'''df4 = df2.melt(id_vars="date",var_name='var_name',value_name='value_name') #自定义对应的列名
print(df4)
'''date   var_name  value_name
0  04-09  Antwerpen        18.0
1  04-10  Antwerpen        16.0
2  04-11  Antwerpen        15.6
3  04-09     London        18.5
4  04-10     London        12.2
5  04-11     London         6.8
6  04-09      Paris         6.5
7  04-10      Paris         7.5
8  04-11      Paris        10.8
'''

3、数据透视表

pivot_table()可以用来组合值的聚合函数(如平均值):

import pandas as pddf = pd.DataFrame({"city": ['Antwerpen', 'Antwerpen', 'Antwerpen', ' Paris', ' Paris', 'Paris', 'Paris', 'London', ' London', 'London'],"country": ['BE', 'BE', 'BE', 'FR', 'FR', 'FR', 'FR', 'GB', 'GB', 'GB'],"parameter": ['pm25', 'no2', 'no2', 'pm25', 'pm25','no2', 'no2', 'pm25', 'no2', 'no2'],"value": [18.0, 6.5, 18.5, 16.0, 7.5, 12.2, 15.6, 10.8, 6.8, 5.5],"unit": ['µg/m³', 'µg/m³', 'µg/m³', 'µg/m³', 'µg/m³','µg/m³', 'µg/m³', 'µg/m³', 'µg/m³', 'µg/m³'],}
)pivot_table = df.pivot_table(values="value", index="country", columns="parameter", aggfunc="mean"
)
print(pivot_table) # 每个站点中 NO2 和 PM2.5 的平均浓度
'''
parameter    no2   pm25
country
BE         12.50  18.00
FR         13.90  11.75
GB          6.15  10.80
'''

如果对每个变量的汇总列感兴趣,可以将 margin 参数设置为 True:

pivot_table = df.pivot_table(values="value", index="country", columns="parameter", aggfunc="mean", margins=True,
)
print(pivot_table)
'''
parameter    no2    pm25        All
country
BE         12.50  18.000  14.333333
FR         13.90  11.750  12.825000
GB          6.15  10.800   7.700000
All        10.85  13.075  11.740000
'''

也许你会觉得奇怪,但pivot_table() 确实是直接连接到groupby()的。

通过对parameter和country进行分组可以得出相同的结果:

print(df.groupby(["parameter", "country"]).mean())
'''value
parameter country
no2       BE       12.50FR       13.90GB        6.15
pm25      BE       18.00FR       11.75GB       10.80
'''

08

合并表

1、连接对象

使用concat() 函数沿其中一个轴(按行或按列)执行多个表的连接操作:

import pandas as pddf_no2 = pd.DataFrame({"city": ['Antwerpen', 'Antwerpen', ' Paris', 'Paris', ' London', 'London'],"country": ['BE', 'BE', 'FR', 'FR', 'GB', 'GB'],"parameter": ['no2', 'no2', 'no2','no2', 'no2', 'no2'],"value": [28.0, 26.5, 27.5, 22.2, 26.8, 25.5],"unit": ['µg/m³', 'µg/m³', 'µg/m³','µg/m³', 'µg/m³', 'µg/m³'],}
)df_pm25 = pd.DataFrame({"city": ['Antwerpen', 'Antwerpen', ' Paris', 'Paris', ' London', 'London'],"country": ['BE', 'BE', 'FR', 'FR', 'GB', 'GB'],"parameter": ['pm25', 'pm25', 'pm25','pm25', 'pm25', 'pm25'],"value": [18.0, 16.5, 17.5, 12.2, 16.8, 15.5],"unit": ['µg/m³', 'µg/m³', 'µg/m³','µg/m³', 'µg/m³', 'µg/m³'],}
)air_quality = pd.concat([df_no2, df_pm25], axis=0) # 连接两个表
print(air_quality.head(12))
'''city country parameter  value   unit
0  Antwerpen      BE       no2   28.0  µg/m³
1  Antwerpen      BE       no2   26.5  µg/m³
2      Paris      FR       no2   27.5  µg/m³
3      Paris      FR       no2   22.2  µg/m³
4     London      GB       no2   26.8  µg/m³
5     London      GB       no2   25.5  µg/m³
0  Antwerpen      BE      pm25   18.0  µg/m³
1  Antwerpen      BE      pm25   16.5  µg/m³
2      Paris      FR      pm25   17.5  µg/m³
3      Paris      FR      pm25   12.2  µg/m³
4     London      GB      pm25   16.8  µg/m³
5     London      GB      pm25   15.5  µg/m³
'''

默认情况下,连接是沿轴 0,所以结果表合并了输入表的行。

让我们检查原始表和连接表的形状以验证操作:

print('Shape of the ``df_no2`` table: ', df_no2.shape)
print('Shape of the ``df_pm25`` table: ', df_pm25.shape)
print('Shape of the resulting ``air_quality`` table: ', air_quality.shape)
'''
Shape of the ``df_no2`` table:  (6, 5)
Shape of the ``df_pm25`` table:  (6, 5)
Shape of the resulting ``air_quality`` table:  (12, 5)
'''

注意:axis 参数将返回许多可以沿轴应用的 pandas 方法。

DataFrame 有两个对应的轴:第一个垂直向下跨行(轴 0),第二个跨列水平运行(轴 1)。

默认情况下,大多数操作(如连接或汇总统计信息)都是跨行(轴 0),但也可以跨列应用。

在这个例子中,数据提供的参数列保证了每个原始表都可以被识别,但并非总会如此。

所以 concat 函数通过 keys 参数提供了一个方便的解决方案,添加了一个额外的(分层的)行索引。

如:

air_quality_ = pd.concat([df_no2, df_pm25], keys=["NO2", "PM25"])
print(air_quality_.head(12))
'''city country parameter  value   unit
NO2  0  Antwerpen      BE       no2   28.0  µg/m³1  Antwerpen      BE       no2   26.5  µg/m³2      Paris      FR       no2   27.5  µg/m³3      Paris      FR       no2   22.2  µg/m³4     London      GB       no2   26.8  µg/m³5     London      GB       no2   25.5  µg/m³
PM25 0  Antwerpen      BE      pm25   18.0  µg/m³1  Antwerpen      BE      pm25   16.5  µg/m³2      Paris      FR      pm25   17.5  µg/m³3      Paris      FR      pm25   12.2  µg/m³4     London      GB      pm25   16.8  µg/m³5     London      GB      pm25   15.5  µg/m³
'''

2、使用通用标识符连接表

使用 merge() 函数,可以对于某表中的每一行,从另一表中添加相应的坐标。

但是两个表都要有共同的列位置,用作组合信息的键。

连接方式如果选择左连接,即表示只有在左表中有位置最终才会出现在结果表中。

import pandas as pddf_coord = pd.DataFrame({"location": ['BELAL01', 'BELHB23', 'BELLD01', 'BELLD02'],"latitude": [51.23619, 51.17030, 51.10998, 51.12038],"longitude": [4.38522, 4.34100, 5.00486, 5.02155],}
)df_air_quality = pd.DataFrame({"location": ['BELAL01', 'BELAL01', 'BELLD01', 'BELLD02', 'BELLD02', 'BELR833'],"parameter": ['pm25', 'no2', 'pm25','pm25', 'no2', 'pm25'],"value": [18.0, 16.5, 17.5, 12.2, 16.8, 15.5],"unit": ['µg/m³', 'µg/m³', 'µg/m³','µg/m³', 'µg/m³', 'µg/m³'],}
)air_quality = pd.merge(df_air_quality, df_coord, how="left", on="location")print(air_quality.head(6))
'''location parameter  value   unit  latitude  longitude
0  BELAL01      pm25   18.0  µg/m³  51.23619    4.38522
1  BELAL01       no2   16.5  µg/m³  51.23619    4.38522
2  BELLD01      pm25   17.5  µg/m³  51.10998    5.00486
3  BELLD02      pm25   12.2  µg/m³  51.12038    5.02155
4  BELLD02       no2   16.8  µg/m³  51.12038    5.02155
5  BELR833      pm25   15.5  µg/m³       NaN        NaN
'''

实例2:

import pandas as pddf_air_quality = pd.DataFrame({"location": ['BELAL01', 'BELAL01', 'BELLD01', 'BELLD02', 'BELLD02', 'BELR833'],"parameter": ['pm25', 'no2', 'pm25','pm25', 'no2', 'pm25'],"value": [18.0, 16.5, 17.5, 12.2, 16.8, 15.5],"unit": ['µg/m³', 'µg/m³', 'µg/m³','µg/m³', 'µg/m³', 'µg/m³'],}
)df_air_quality_parameters = pd.DataFrame({"id": ['bc', 'co', 'no2', 'pm25'],"name": ['BC', 'CO', 'NO3', 'PM25'],}
)air_quality = pd.merge(df_air_quality, df_air_quality_parameters,how='left', left_on='parameter', right_on='id')print(air_quality.head(6))
'''location parameter  value   unit    id  name
0  BELAL01      pm25   18.0  µg/m³  pm25  PM25
1  BELAL01       no2   16.5  µg/m³   no2   NO3
2  BELLD01      pm25   17.5  µg/m³  pm25  PM25
3  BELLD02      pm25   12.2  µg/m³  pm25  PM25
4  BELLD02       no2   16.8  µg/m³   no2   NO3
5  BELR833      pm25   15.5  µg/m³  pm25  PM25
'''

与第一个实例相比,实例2没有相同的列名。

但是,df_air_quality表中的 parameter列和 df_air_quality_parameters 中的 id 列都是以相同的格式提供测量变量的。

并且此处是使用 left_on 和 right_on 参数(而不仅仅是 on)来建立两个表之间的链接。

09

处理时间序列数据

1、使用datetime属性

可以通过 to_datetime 函数将日期时间列中的日期用作datetime对象而不是纯文本:

import pandas as pddf = pd.DataFrame({"datetime": ["2019-06-20 23:00:00+00:00","2019-06-20 22:00:00+00:00","2019-06-20 21:00:00+00:00","2019-06-20 20:00:00+00:00","2019-06-20 19:00:00+00:00","2019-06-20 18:00:00+00:00",],"parameter": ['pm25', 'pm25', 'pm25','pm25', 'pm25', 'pm25'],"value": [18.0, 16.5, 17.5, 12.2, 16.8, 15.5],"unit": ['µg/m³', 'µg/m³', 'µg/m³','µg/m³', 'µg/m³', 'µg/m³'],}
)df["datetime"] = pd.to_datetime(df["datetime"])print(df["datetime"])
'''
0   2019-06-20 23:00:00+00:00
1   2019-06-20 22:00:00+00:00
2   2019-06-20 21:00:00+00:00
3   2019-06-20 20:00:00+00:00
4   2019-06-20 19:00:00+00:00
5   2019-06-20 18:00:00+00:00
Name: datetime, dtype: datetime64[ns, UTC]
'''

最初,datetime中的值是字符串,不提供任何datetime操作(例如,提取年份、星期几……)。

但是通过应用 to_datetime 函数,pandas 可以解释字符串并将它们转换为datetime(即 datetime64[ns, UTC])对象。

在 pandas 中,我们将这些类似于标准库中的 datetime.datetime 的日期时间对象称为 pandas.Timestamp。

注意:pandas 输入函数(如 pandas.read_csv() )可以使用 parse_dates参数和一个列的时间戳列表来进行日期转换:

pd.read_csv("air_quality.csv", parse_dates=["datetime"])

那为什么要转换成 pandas.Timestamp 对象?

让我们通过一些示例来说明其转换价值:

print(df["datetime"].min(), df["datetime"].max()) #时间序列数据集的开始和结束日期
'''
2019-06-20 18:00:00+00:00 2019-06-20 23:00:00+00:00
'''print(df["datetime"].max() - df["datetime"].min()) # 获取时间序列的间隔
'''
0 days 05:00:00
'''

通过把日期转换成 Timestamp 对象,可以使用许多与时间相关的属性。

例如月份month、年份year、一年中的一周weekofyear、季度quarte……所有这些属性都可以通过 dt 访问器访问。

df["month"] = df["datetime"].dt.month
print(df.head(6))
'''datetime parameter  value   unit  month
0 2019-06-20 23:00:00+00:00      pm25   18.0  µg/m³      6
1 2019-06-20 22:00:00+00:00      pm25   16.5  µg/m³      6
2 2019-06-20 21:00:00+00:00      pm25   17.5  µg/m³      6
3 2019-06-20 20:00:00+00:00      pm25   12.2  µg/m³      6
4 2019-06-20 19:00:00+00:00      pm25   16.8  µg/m³      6
5 2019-06-20 18:00:00+00:00      pm25   15.5  µg/m³      6
'''

我们也可以利用 groupby 和Timestamp 的 datetime 属性 (如day)对日期进行分组,然后计算每个组合的平均值。

import pandas as pddf = pd.DataFrame({"datetime": ["2019-06-20 23:00:00+00:00","2019-06-20 22:00:00+00:00","2019-06-21 23:00:00+00:00","2019-06-21 22:00:00+00:00","2019-06-22 23:00:00+00:00","2019-06-22 22:00:00+00:00",],"parameter": ['pm25', 'pm25', 'pm25','pm25', 'pm25', 'pm25'],"value": [18.0, 16.5, 17.5, 12.2, 16.8, 15.5],"unit": ['µg/m³', 'µg/m³', 'µg/m³','µg/m³', 'µg/m³', 'µg/m³'],}
)df["datetime"] = pd.to_datetime(df["datetime"])df_mean_day = df.groupby([df["datetime"].dt.day])["value"].mean()
print(df_mean_day)
'''
datetime
20    17.25
21    14.85
22    16.15
Name: value, dtype: float64
'''

2、Datetime作为索引

在重塑的教程中,我们引入了 pivot() 来重塑数据表:

import pandas as pddf = pd.DataFrame({"datetime": ["2019-06-20 23:00:00+00:00","2019-06-20 22:00:00+00:00","2019-06-21 23:00:00+00:00","2019-06-21 22:00:00+00:00","2019-06-22 23:00:00+00:00","2019-06-22 22:00:00+00:00",],"parameter": ['pm25', 'pm25', 'pm25','pm25', 'pm25', 'pm25'],"value": [18.0, 16.5, 17.5, 12.2, 16.8, 15.5],"unit": ['µg/m³', 'µg/m³', 'µg/m³','µg/m³', 'µg/m³', 'µg/m³'],}
)
df["datetime"] = pd.to_datetime(df["datetime"])
df_2 = df.pivot(index="datetime", columns="parameter", values="value")
print(df_2.head())
'''
parameter                  pm25
datetime
2019-06-20 22:00:00+00:00  16.5
2019-06-20 23:00:00+00:00  18.0
2019-06-21 22:00:00+00:00  12.2
2019-06-21 23:00:00+00:00  17.5
2019-06-22 22:00:00+00:00  15.5
'''

重塑之后,日期时间信息将成为表的索引,使用日期时间索引(即 DatetimeIndex)可以提供强大的功能。

如,我们可以不需要通过 dt 访问器来获取时间序列属性,而是让这些属性直接在索引上可用。

ps:一般来说,设置一列作为索引是通过set_index函数来实现的。

print(df_2.index.year,'\n',df_2.index.weekday)
'''
Int64Index([2019, 2019, 2019, 2019, 2019, 2019], dtype='int64', name='datetime') Int64Index([3, 3, 4, 4, 5, 5], dtype='int64', name='datetime')
'''

其他一些优点是,可以方便地对时间段进行细分,或者在图表上调整时间尺度。

比如只想绘制6月20日的数据:

import matplotlib.pyplot as plt
df_2["2019-06-20 22:00:00+00:00":"2019-06-20 23:00:00+00:00"].plot()
plt.show()  # 显示图表

效果:

3、将时间序列重新采样到另一个频率

具有datetime索引的时间序列数据的一个非常强大的方法是能够将时间序列 resample()到另一个频率。

resample() 方法类似于 groupby 操作:

  • 它通过使用定义目标频率的字符串(例如 M、5H、...)来提供基于时间的分组

  • 它需要一个聚合函数,例如平均值mean、最大值max、...

day_max = df_2.resample("D").max() # 一天的最大值
print(day_max)
'''
parameter                  pm25
datetime
2019-06-20 00:00:00+00:00  18.0
2019-06-21 00:00:00+00:00  17.5
2019-06-22 00:00:00+00:00  16.8
'''

定义后,时间序列的频率由 freq 属性提供:

print(day_max.index.freq)   # <Day>

10

操作文本数据

与时间序列教程中具有dt访问器的datetime对象类似,在使用str访问器时,有许多专门的字符串方法可用。

对于单个元素,这些方法具有通用的匹配名称和等效的内置字符串方法,但是对列的每个值是以应用元素的方式。

1、lower()

lower()方法可以转换字符串中所有大写字符为小写。

比如想将 Name 列中的每个字符串变为小写,需要选择 Name 列,然后添加 str 访问器并应用 lower 方法。

import pandas as pd # 一般命名为pddf = pd.DataFrame({"Name": ["Braund, Mr. Owen Harris","Allen, Mr. William Henry","Bonnell, Miss. Elizabeth",],"Age": [22, 35, 58],"Sex": ["male", "male", "female"],}
)
name_lower = df["Name"].str.lower() # 使所有名字字符变成小写
print(name_lower )
'''
0     braund, mr. owen harris
1    allen, mr. william henry
2    bonnell, miss. elizabeth
Name: Name, dtype: object
'''

2、split()

使用 Series.str.split() 方法,可以把每个值都作为 2 个元素的列表返回。

其中第一个元素是分隔符之前的部分,第二个元素是分隔符之后的部分。

name_list = df["Name"].str.split(",")
print(name_list)
'''
0     [Braund,  Mr. Owen Harris]
1    [Allen,  Mr. William Henry]
2    [Bonnell,  Miss. Elizabeth]
Name: Name, dtype: object
'''

3、get()

可以使用 str 访问器并应用 Series.str.get() 来提取列表元素:

name_first = name_list.str.get(0)
print(name_first)
'''
0     Braund
1      Allen
2    Bonnell
Name: Name, dtype: object
'''

4、contains()

Series.str.contains() 方法会检查某列中的每个值,并为每个值返回 True(包含指定字符串)或 False(不包含指定字符串)。

如查看Name列里是否包含字符串Bonnell:

name_contain_Bonnell = df["Name"].str.contains("Bonnell") # 查看是否包含字符串Bonnell
print(name_contain_Bonnell)
'''
0    False
1    False
2     True
Name: Name, dtype: bool
'''contain_Bonnell = df[df["Name"].str.contains("Bonnell")] #返回包含Bonnell的行数据
print(contain_Bonnell)
'''Name  Age     Sex
2  Bonnell, Miss. Elizabeth   58  female
'''

5、len() & idxmax()

Series.str.len() 可以获得字符串的长度:

name_len = df["Name"].str.len() #获得字符串的长度
print(name_len)
'''
0    23
1    24
2    24
Name: Name, dtype: int64
'''

但如果我们需要获取名称长度最大的表中对应的位置,最好是获取其索引标签,这可以通过idxmax() 实现。

但idxmax() 不是字符串方法,只适用于整数,因此不要使用 str。

name_len_max = name_len.idxmax() # 获取长度最大的名字对应的索引标签
print(name_len_max) # 1row_len_max = df.loc[name_len_max, "Name"] #获取长度最大的名字
print(row_len_max)  #Allen, Mr. William Henry

6、replace()

虽然 replace() 不是字符串方法,但它可以通过字典{from : to}来定义映射从而替换某些值。

如:

df["Sex_short"] = df["Sex"].replace({"male": "M", "female": "F"}) # 新添一列,把male换成M,把female换成F
print(df.head())
'''Name  Age     Sex Sex_short
0   Braund, Mr. Owen Harris   22    male         M
1  Allen, Mr. William Henry   35    male         M
2  Bonnell, Miss. Elizabeth   58  female         F
'''

字符串也有 replace() 方法用于替换字符串,但是比较麻烦,也容易导致错误。

如:

df["Sex_short"] = df["Sex"].str.replace("female", "F")
df["Sex_short"] = df["Sex_short"].str.replace("male", "M")
print(df.head())
'''Name  Age     Sex Sex_short
0   Braund, Mr. Owen Harris   22    male         M
1  Allen, Mr. William Henry   35    male         M
2  Bonnell, Miss. Elizabeth   58  female         F
'''

好啦,pandas的入门教程就到这。

如果对pandas有兴趣的话可以关注山月哦~接下来,山月还会对pandas进行一些介绍。

END

您的“点赞”、“在看”和 “分享”是我们产出的动力。

Python自动化办公:pandas入门教程相关推荐

  1. Python自动化办公:openpyxl教程(进阶)

    在后台回复[阅读书籍] 即可获取python相关电子书~ Hi,我是山月. 之前给大家分享了openpyxl的基础教程:Python自动化办公:openpyxl教程(基础).不知道大家学习的怎么样了. ...

  2. Python自动化办公:openpyxl教程(基础)

    在后台回复[阅读书籍] 即可获取python相关电子书~ Hi,我是山月. 前面给大家介绍了xlrd.xlwt的教程?? Python自动化办公:xlrd万字教程 Python自动化办公:xlwt万字 ...

  3. python做数据处理软件_程序员用于机器学习编程的Python 数据处理库 pandas 入门教程...

    入门介绍 pandas适合于许多不同类型的数据,包括: · 具有异构类型列的表格数据,例如SQL表格或Excel数据 · 有序和无序(不一定是固定频率)时间序列数据. · 具有行列标签的任意矩阵数据( ...

  4. Python自动化办公社区 · 最新教程

  5. python使用教程pandas-Python 数据处理库 pandas 入门教程基本操作

    pandas是一个Python语言的软件包,在我们使用Python语言进行机器学习编程的时候,这是一个非常常用的基础编程库.本文是对它的一个入门教程. pandas提供了快速,灵活和富有表现力的数据结 ...

  6. Python自动化办公:word文件操作教程

    在后台回复[阅读书籍] 即可获取python相关电子书~ Hi,我是山月. 之前给大家完整的介绍了用python操作excel的几个库:xlrd.xlwt.openpyxl. 山月也已经整理好了,还没 ...

  7. Python自动化办公:openpyxl绘制图表

    在后台回复[阅读书籍] 即可获取python相关电子书~ Hi,我是山月. 之前给大家分享了openpyxl的基础和进阶教程: Python自动化办公:openpyxl教程(基础) Python自动化 ...

  8. 推荐7个Python自动化办公免费学习资源~(数据分析、Python、VBA等)

    欢迎大家收藏学习.留言分享你的学习收获,也欢迎将本文转发给需要的朋友哦- 1.Python自动化办公(2021最新版!有源代码 ,适合小白~) 课程链接:https://www.bilibili.co ...

  9. python自动化办公入门故事教案_Python自动化办公知识点整理汇总

    知乎上有人提问:用python进行办公自动化都需要学习什么知识呢? 这可能是很多非IT职场人士面临的困惑,想把python用到工作中,却不知如何下手?python在自动化办公领域越来越受欢迎,批量处理 ...

  10. python自动化办公教程书籍_盘点使用Python进行自动化办公所需要的知识点

    知乎上有人提问:用python进行办公自动化都需要学习什么知识呢? 这可能是很多非IT职场人士面临的困惑,想把python用到工作中,却不知如何下手?python在自动化办公领域越来越受欢迎,批量处理 ...

最新文章

  1. Java并发:分布式应用限流 Redis + Lua 实践
  2. C++——类访问修饰符
  3. Qt 中Treewidget添加右键菜单
  4. 数组长度属性以及JavaScript中的示例
  5. stanford-parser for C#
  6. 和为S(51Nod-2518)
  7. [DFS] [BFS] poj1979 poj3009 poj3669
  8. lldp协议代码阅读_microsoft,lldp协议
  9. 从全班同学的成绩中找出最高成绩(遍历一位数组)
  10. KDE桌面下konsole打开terminal/tab 并执行命令或脚本
  11. 面试被问扔鸡蛋问题:100层扔鸡蛋问题(扔球问题)
  12. qpython教程_qpython教程
  13. Npm配置全局安装插件目录以及命令用法扩展
  14. CC2530 ADC学习
  15. centos安装Nvidia显卡驱动(3090)
  16. EXCEL基本功能 --- 数据透视表
  17. 微软研发类实习生面试
  18. 7、全国天气查询API接口,免费好用
  19. 基于知识图谱的玉米病虫害知识问答(一)
  20. 微信公众号项目开发笔记 一

热门文章

  1. java bearer token_从Web API在MVC中存储Bearer Token的位置
  2. 你必须知道的linux开发快捷键,熟知工具快速开发
  3. 竞赛排名_纪中1743_模拟
  4. Excel中查找比对VLOOKUP()函数的使用方法一
  5. FineBI连接本地Mysql数据库
  6. 省选+NOI 第一部分 动态规划DP
  7. 电商巨头的「隐秘」战场
  8. 基于python的梯度下降法的实现代码
  9. 期初余额、期后事项审计与审计报告案例
  10. in作为介词的用法_语法专题:介词in的使用规则