Python自动化办公:pandas入门教程
在后台回复【阅读书籍】
即可获取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入门教程相关推荐
- Python自动化办公:openpyxl教程(进阶)
在后台回复[阅读书籍] 即可获取python相关电子书~ Hi,我是山月. 之前给大家分享了openpyxl的基础教程:Python自动化办公:openpyxl教程(基础).不知道大家学习的怎么样了. ...
- Python自动化办公:openpyxl教程(基础)
在后台回复[阅读书籍] 即可获取python相关电子书~ Hi,我是山月. 前面给大家介绍了xlrd.xlwt的教程?? Python自动化办公:xlrd万字教程 Python自动化办公:xlwt万字 ...
- python做数据处理软件_程序员用于机器学习编程的Python 数据处理库 pandas 入门教程...
入门介绍 pandas适合于许多不同类型的数据,包括: · 具有异构类型列的表格数据,例如SQL表格或Excel数据 · 有序和无序(不一定是固定频率)时间序列数据. · 具有行列标签的任意矩阵数据( ...
- Python自动化办公社区 · 最新教程
- python使用教程pandas-Python 数据处理库 pandas 入门教程基本操作
pandas是一个Python语言的软件包,在我们使用Python语言进行机器学习编程的时候,这是一个非常常用的基础编程库.本文是对它的一个入门教程. pandas提供了快速,灵活和富有表现力的数据结 ...
- Python自动化办公:word文件操作教程
在后台回复[阅读书籍] 即可获取python相关电子书~ Hi,我是山月. 之前给大家完整的介绍了用python操作excel的几个库:xlrd.xlwt.openpyxl. 山月也已经整理好了,还没 ...
- Python自动化办公:openpyxl绘制图表
在后台回复[阅读书籍] 即可获取python相关电子书~ Hi,我是山月. 之前给大家分享了openpyxl的基础和进阶教程: Python自动化办公:openpyxl教程(基础) Python自动化 ...
- 推荐7个Python自动化办公免费学习资源~(数据分析、Python、VBA等)
欢迎大家收藏学习.留言分享你的学习收获,也欢迎将本文转发给需要的朋友哦- 1.Python自动化办公(2021最新版!有源代码 ,适合小白~) 课程链接:https://www.bilibili.co ...
- python自动化办公入门故事教案_Python自动化办公知识点整理汇总
知乎上有人提问:用python进行办公自动化都需要学习什么知识呢? 这可能是很多非IT职场人士面临的困惑,想把python用到工作中,却不知如何下手?python在自动化办公领域越来越受欢迎,批量处理 ...
- python自动化办公教程书籍_盘点使用Python进行自动化办公所需要的知识点
知乎上有人提问:用python进行办公自动化都需要学习什么知识呢? 这可能是很多非IT职场人士面临的困惑,想把python用到工作中,却不知如何下手?python在自动化办公领域越来越受欢迎,批量处理 ...
最新文章
- Java并发:分布式应用限流 Redis + Lua 实践
- C++——类访问修饰符
- Qt 中Treewidget添加右键菜单
- 数组长度属性以及JavaScript中的示例
- stanford-parser for C#
- 和为S(51Nod-2518)
- [DFS] [BFS] poj1979 poj3009 poj3669
- lldp协议代码阅读_microsoft,lldp协议
- 从全班同学的成绩中找出最高成绩(遍历一位数组)
- KDE桌面下konsole打开terminal/tab 并执行命令或脚本
- 面试被问扔鸡蛋问题:100层扔鸡蛋问题(扔球问题)
- qpython教程_qpython教程
- Npm配置全局安装插件目录以及命令用法扩展
- CC2530 ADC学习
- centos安装Nvidia显卡驱动(3090)
- EXCEL基本功能 --- 数据透视表
- 微软研发类实习生面试
- 7、全国天气查询API接口,免费好用
- 基于知识图谱的玉米病虫害知识问答(一)
- 微信公众号项目开发笔记 一