为什么你需要pandas
大家好,今天想和大家分享一下有关pandas的学习新的,我因工作需要,从去年12月开始接触这个非常好用的包,到现在为止也是算是熟悉了一些,因此发现了它的强大之处,特意想要和朋友们分享,特别是如果你每天和excel打交道,总是需要编写一些vba函数或者对行列进行groupby啊,merge,join啊之类的,相信我,pandas会让你解脱的。
好啦,闲话少说,这篇文章的基础是假设你已经大概听说过了pandas的一些概念和用途,如果还大体上不太清楚的朋友们,可以去百度一下相关基础介绍,本分主要分成四个部分:
从Dataframe说起 : 简单了解Df这种数据结构,了解如何创建一个Df
Dataframe基础操作 :基于行,列,index选取数据,新增数据,删除数据
Pandas 读取 / 导出数据: 了解如何对excel,csv,tsv等常见文件进行读取并导出
总结: 精华部分,为大家总结一些非常实用的一些方法,并附带源码 ipynb以及py文件提供下载
1. 从Dataframe说起首先,让我们明确一点,pandas这个包是在numpy的基础上得到的,因此可能有的朋友会有疑问,要不要先学学numpy,我的个人建议是真的不太需要,因为大多数的情况下基本用不到,当然,如果你处理的是科学实验类型的数据的话,当我没说,我这里的应用场景主要是一般类型的常见数据,比如:
你是销售经理,经常需要汇总各地区的销售情况
你在银行工作,不可避免的需要和数字,excel打交道
你每天有很多重复的工作,比如备份,计算两表合并,分组,聚类等等。。。。。。
这种情况下,学习pandas会非常有用,这里我们说的数据都是二维的table,在pandas中也称作dataframe。
pandas中其实一共有三种类型的常见数据:
数据结构 | 维度 | 说明 |
---|---|---|
Series | 1 | 类似list,一维数组 |
Data Frames | 2 | 最常见的二维数据结构,excel,sql的表就是这个 |
Panel | 3 | 用的很少,三维结构 |
pandas主要包括三类数据结构,分别是:
Series:一维数组,与Numpy中的一维array类似。二者与Python基本的数据结构List也很相近,其区别是:List中的元素可以是不同的数据类型,而Array和Series中则只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率。
DataFrame:二维的表格型数据结构。很多功能与R中的data.frame类似。可以将DataFrame理解为Series的容器。以下的内容主要以DataFrame为主。
Panel :三维的数组,可以理解为DataFrame的容器。
Pandas官网,更多功能请参考 http://pandas-docs.github.io/...
这里我们主要聚焦在Dataframe上,一个dataframe长的基本上如下这番模样:
Name | Age | Mark |
---|---|---|
John | 15 | 78 |
Mike | 23 | 86 |
Mary | 36 | 95 |
我们把这个简单的dataframe起个名字叫df,那么它包括的最基础的元素有:
index:每行的索引,默认是从0开始,比如上面的df[0] 就是指 John 15 78这一行,依次类推,当然我们可以自己规定index,我以后会说
columns:列。这里就是指的是Name Age Mark 了
rows:行,df一共有3行
现在让我们看一个完整的图示:
Dataframe 是应用最多也是最广泛的数据结构,现在就让我们开始学习创建一个dataframe吧~
1.1 创建Dataframe创建一个Dataframe的方法有很多,总体上来说最常见的有及种:
创建空dataframe
利用dict创建
从其他数据源读取(网站,excel,mysql等)
真实场景中大多数都是从其他数据源读取,我们会在第3部分讲到
创建空dataframe
这个非常简单:
import pandas as pd # Calling DataFrame constructor df = pd.DataFrame() print(df) Out:Empty DataFrame Columns: [] Index: []
利用dict创建(1)
import pandas as pd print (f" Using {pd.__name__},Version {pd.__version__}") Out: Using pandas , version 0.23.4
首先要import pandas 包,这里缩写为pd,现在让我们从dict创建一个dataframe:
>>> dict = {"name":["Tom", "Bob", "Mary", "James"], "age": [18, 30, 25, 40], "city":["Beijing", "ShangHai","GuangZhou", "ShenZhen"]} >>> df = pd.DataFrame(dict) >>> df
创建结果如下:
age | city | name | |
---|---|---|---|
0 | 18 | Beijing | Tom |
1 | 30 | ShangHai | Bob |
2 | 25 | GuangZhou | Mary |
3 | 40 | ShenZhen | James |
很简单是不是,大家可能发现了,最左边的东西就是index ,0,1,2,3,如果我们不指定会自动生成从0默认开始的序列,一直到你的dataframe的最后一行,类似于excel左边的编号
利用dict创建(2)
这次让我们创建的更加规范一些:
index = pd.Index(["Tom", "Bob", "Mary", "James"],name = "person") cols = ["age","city"] data = [[18,"Beijing"], [30,"ShangHai"], [25,"GuangZhou"], [40,"ShenZhen"]] df =pd.DataFrame(index = index,data =data,columns = cols) df
age | city | |
---|---|---|
person | ||
Tom | 18 | Beijing |
Bob | 30 | ShangHai |
Mary | 25 | GuangZhou |
James | 40 | ShenZhen |
这里的主要区别在于我们主动规定了‘name’列为索引。这种把一列默认为索引的方式在excel和sql里都有,异曲同工
从其他数据源读取(网站,excel,mysql等)
我会在第三部分介绍最常用的从excel,csv等读取数据
总体来说,有关创建Dataframe的部分我们不用了解太多,因为实际的场景基本不需要,都是直接从csv,tsv,sql,json等数据源直接获取。
2. Dataframe 基础操作这里我们主要看一下基于索引,行,列,行和列的基础操作,最后会为大家总结一下,现在拿刚刚我们创建过的dataframe为例:
age | city | name | |
---|---|---|---|
0 | 18 | Beijing | Tom |
1 | 30 | ShangHai | Bob |
2 | 25 | GuangZhou | Mary |
3 | 40 | ShenZhen | James |
添加新列
添加一列非常简单:
df["country"] = "USA" df
age | city | name | country | |
---|---|---|---|---|
0 | 18 | Beijing | Tom | USA |
1 | 30 | ShangHai | Bob | USA |
2 | 25 | GuangZhou | Mary | USA |
3 | 40 | ShenZhen | James | USA |
df["adress"] = df["country"] df
age | city | name | country | adress | |
---|---|---|---|---|---|
0 | 18 | Beijing | Tom | USA | USA |
1 | 30 | ShangHai | Bob | USA | USA |
2 | 25 | GuangZhou | Mary | USA | USA |
3 | 40 | ShenZhen | James | USA | USA |
修改列中的值
修改一个列的值也是很容易的,我们可以这样做:
df["country"] = "China" df
age | city | name | country | adress | |
---|---|---|---|---|---|
0 | 18 | Beijing | Tom | China | USA |
1 | 30 | ShangHai | Bob | China | USA |
2 | 25 | GuangZhou | Mary | China | USA |
3 | 40 | ShenZhen | James | China | USA |
或者稍微多想一步:
df["adress"] = df["city"]+","+ df["country"] df
age | city | name | country | adress | |
---|---|---|---|---|---|
0 | 18 | Beijing | Tom | China | Beijing,China |
1 | 30 | ShangHai | Bob | China | ShangHai,China |
2 | 25 | GuangZhou | Mary | China | GuangZhou,China |
3 | 40 | ShenZhen | James | China | ShenZhen,China |
删除列
我们可以应用del或者drop函数,如果是drop,要注意传参时要加上axis = 1.这里简单和大家说明一下axis,这个东西其实就是指轴向,默认的axis=0,是纵向,axis=1是横向
df.drop("country",axis=1) df
age | city | name | adress | |
---|---|---|---|---|
0 | 18 | Beijing | Tom | Beijing,China |
1 | 30 | ShangHai | Bob | ShangHai,China |
2 | 25 | GuangZhou | Mary | GuangZhou,China |
3 | 40 | ShenZhen | James | ShenZhen,China |
del df["city"] df
age | name | adress | |
---|---|---|---|
0 | 18 | Tom | Beijing,China |
1 | 30 | Bob | ShangHai,China |
2 | 25 | Mary | GuangZhou,China |
3 | 40 | James | ShenZhen,China |
这里有一点大家需要注意:
drop和del的结果是基于df的两次多带带操作,并不是连续的
如果我们执行完drop后,重新查看df,这时你会发现df没有变化,因为没有真正的删除
要想真正删除,需要加上关键字 inplace = True
因此如果我们想要连续删除country和city这两列,改进后的代码如下:
df.drop("country",axis=1, inplace=True) del df["city"] df
age | name | adress | |
---|---|---|---|
0 | 18 | Tom | Beijing,China |
1 | 30 | Bob | ShangHai,China |
2 | 25 | Mary | GuangZhou,China |
3 | 40 | James | ShenZhen,China |
选取列
这个非常简单,实现代码如下:
df["age"] # 选取age这一列 0 18 1 30 2 25 3 40 Name: age, dtype: int64
或者这样:
df.name
0 Tom 1 Bob 2 Mary 3 James Name: name, dtype: object
如果想要选取多个列也很容易,传递一个list就行啦:
df[["age","name"]]
age | name | |
---|---|---|
0 | 18 | Tom |
1 | 30 | Bob |
2 | 25 | Mary |
3 | 40 | James |
这里注意,和选取多带带一列不同,这里我们返回的类型是dataframe,之前的类型是series,我们可以这么理解,一列其实还是一维数组,但是两列及以上是二维的了,当然类型也变了
如果我们想要查看当前的所有列:
df.columns Out:Index([u"age", u"name", u"adress"], dtype="object")
如果我们想要重新对列进行命名,基本有三种方法,大家挑一种自己喜欢的就行
传递list
传递dict
传递 axis
用list:
df.columns = ["Age","Name","Adress"] df
用dict:
df.rename(index = str, columns = {"age":"Age","name":"Name","adress":"Adress"}) #这里index=str 有没有都行,我这么做是为了规范 df
用axis:
df.rename(str.capitalize, axis="columns",inplace =True) df
最后得到的效果是一样的:
Age | Name | Adress | |
---|---|---|---|
0 | 18 | Tom | Beijing,China |
1 | 30 | Bob | ShangHai,China |
2 | 25 | Mary | GuangZhou,China |
3 | 40 | James | ShenZhen,China |
根据条件给列赋值
我们现在想要根据人的年龄新增一列 Group,假设要求如下:
18岁以下的是年轻人
18-30的是中年人
30以上的是老年人
我们有很多方法可以实现,先看一种,大家可以先忽视loc方法,这里传达的就是基础思路:
df["Group"] = "elderly" df.loc[df["Age"]<=18, "Group"] = "young" df.loc[(df["Age"] >18) & (df["Age"] <= 30), "Group"] = "middle_aged" df
Age | Name | Adress | Group | |
---|---|---|---|---|
0 | 18 | Tom | Beijing,China | young |
1 | 30 | Bob | ShangHai,China | middle_aged |
2 | 25 | Mary | GuangZhou,China | middle_aged |
3 | 40 | James | ShenZhen,China | elderly |
loc函数 df.loc[row,column]
首先,大多数对于行的操作都可以通过loc函数实现,比如我们想要选取全部的行,除了直接打出df外,可以使用df.loc[:]
df.loc[:]
Age | Name | Adress | Group | |
---|---|---|---|---|
0 | 18 | Tom | Beijing,China | young |
1 | 30 | Bob | ShangHai,China | middle_aged |
2 | 25 | Mary | GuangZhou,China | middle_aged |
3 | 40 | James | ShenZhen,China | elderly |
loc函数条件查询
df.loc[df["Age"]>20]
Name | Age | Adress | Group | |
---|---|---|---|---|
1 | Bob | 30 | ShangHai,China | middle_aged |
2 | Mary | 25 | GuangZhou,China | middle_aged |
3 | James | 40 | ShenZhen,China | elderly |
loc函数条件行列查询
df.loc[df["Group"]=="middle_aged","Name"] 1 Bob 2 Mary Name: Name, dtype: object
Where 查询
filter_adult = df["Age"]>25 result = df.where(filter_adult) result
Name | Age | Adress | Group | |
---|---|---|---|---|
0 | NaN | NaN | NaN | NaN |
1 | Bob | 30.0 | ShangHai,China | middle_aged |
2 | NaN | NaN | NaN | NaN |
3 | James | 40.0 | ShenZhen,China | elderly |
Query 筛选
# df.query("Age==30") df.query("Group=="middle_aged""and "Age>30" )
Name | Age | Adress | Group | |
---|---|---|---|---|
3 | James | 40 | ShenZhen,China | elderly |
这里有很多有用的方法,可以帮助到大家大致了解数据的情况:
df.shape # 了解行列情况 Out:(4, 4)
df.describe() # 获取可计算列基础统计
Age | |
---|---|
count | 4.000000 |
mean | 28.250000 |
std | 9.251126 |
min | 18.000000 |
25% | 23.250000 |
50% | 27.500000 |
75% | 32.500000 |
max | 40.000000 |
# df.head(3) #查看前三行数据,默认为5 df.tail(3) #获得最后三行数据
Name | Age | Adress | Group | |
---|---|---|---|---|
1 | Bob | 30 | ShangHai,China | middle_aged |
2 | Mary | 25 | GuangZhou,China | middle_aged |
3 | James | 40 | ShenZhen,China | elderly |
Pandas 支持大部分常见数据文件读取与存储。一般清楚下,读取文件的方法以 pd.read_ 开头,而写入文件的方法以 pd.to_ 开头。这里我们开始熟悉一下最实用的对于csv文件的读取写入
写入CSV
df.to_csv("person.csv",index=None,sep=",")
import os os.getcwd() Out: "C:UsersE560"
这样大家就可以在"C:UsersE560"的路径下找到我们刚刚生成的csv文件了,这里我把index=None,舍弃了索引值
读取CSV
首先我们确认和python文件同一目录下存在我们刚刚导出的person.csv文件,之后可以很容易的读取了:
person = pd.read_csv("person.csv") person
Name | Age | Adress | Group | |
---|---|---|---|---|
0 | Tom | 18 | Beijing,China | young |
1 | Bob | 30 | ShangHai,China | middle_aged |
2 | Mary | 25 | GuangZhou,China | middle_aged |
3 | James | 40 | ShenZhen,China | elderly |
这时我们发现,即使我们读取的csv文件没有索引,但是pandas已经默认帮我们加上了
4. 总结,资料下载好了,现在大家对pandas的使用已经有了基础的印象,我给大家简单总结一下常用的方法:
使用标签选取数据
df.loc[行标签,列标签] df.loc["Tom":"Mary"] #选取 Tom至Mary的所有行的数据,Tom和Mary是index df.loc[:,"city"] #选取 city 列的数据
df.loc 的第一个参数是行标签,第二个参数为列标签(可选参数,默认为所有列标签),两个参数既可以是列表也可以是单个字符,如果两个参数都为列表则返回的是 DataFrame,否则,则为 Series。
PS:loc为location的缩写。
使用位置(index)选取数据
df.iloc[行位置,列位置] df.iloc[1,1] #选取第二行,第二列的值,返回的为单个值 df.iloc[[0,2],:] #选取第一行及第三行的数据 df.iloc[0:2,:] #选取第一行到第三行(不包含)的数据 df.iloc[:,1] #选取所有记录的第二列的值,返回的为一个Series df.iloc[1,:] #选取第一行数据,返回的为一个Series
PS:iloc 则为 integer & location 的缩写
通过逻辑指针进行数据切片
df[逻辑条件] df[df.age >= 18] #单个逻辑条件 df[(df.age >=18 ) & (df.country=="China") ] #多个逻辑条件组合
了解并掌握数据大致情况
方法 | 解释 |
---|---|
count | 非na值的数量 |
describe | 针对Series或个DataFrame列计算汇总统计 |
min、max | 计算最小值和最大值 |
argmin、argmax | 计算能够获取到最大值和最小值得索引位置(整数) |
idxmin、idxmax | 计算能够获取到最大值和最小值得索引值 |
quantile | 计算样本的分位数(0到1) |
sum | 值的总和 |
mean | 值得平均数 |
median | 值得算术中位数(50%分位数) |
mad | 根据平均值计算平均绝对离差 |
var | 样本值的方差 |
std | 样本值的标准差 |
skew | 样本值得偏度(三阶矩) |
kurt | 样本值得峰度(四阶矩) |
cumsum | 样本值得累计和 |
cummin,cummax | 样本值得累计最大值和累计最小值 |
cumprod | 样本值得累计积 |
diff | 计算一阶差分(对时间序列很有用) |
pct_change | 计算百分数变化 |
常见读取写入数据
数据类型 | 读取 | 写入 |
---|---|---|
CSV | read_csv | to_csv |
JSON | read_json | to_json |
HTML | read_html | to_html |
EXCEL | read_excel | to_excel |
SQL | read_sql | to_sql |
好了,其实这些就是想要告诉大家如何学习pandas,没有必要了解每一个方法,但是现在想必你知道pandas能实现的功能很多,这样你有具体需求时只要详细查询一下文档即可,接下来几期我们会重点来看pandas里面对于df的各种操作,从简单的数据清理到类似于excel里面的vba,包括cancat,merge,join等等
下载
我把这一期的ipynb文件和py文件放到了GIthub上,大家如果想要下载可以点击下面的链接:
Github仓库地址: 点我下载
好啦,这一期就讲这么多,希望大家能够继续支持我,完结,撒花
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/43298.html
摘要:数据清洗大家好,这一期我将为大家带来我的学习心得第二期数据清理。这一期我会和大家分享一些比较好用常见的清洗方法。首先还是让我们来简单看一下本文将会用到的数据源这是一个超小型的房地产行业的数据集,大家会在文章最后找到下载地址。 数据清洗 大家好,这一期我将为大家带来我的pandas学习心得第二期:数据清理。这一步非常重要,一般在获取数据源之后,我们紧接着就要开始这一步,以便为了之后的各种...
摘要:,同为小白的朋友们大家好,这期主要为大家带来有关字典的一些实用技巧。上篇笔记通过感人肺腑的老白让大家认识到了字典这么有用的数据类型,这一期让我们看看如何能更好的操作字典。 Hello ,同为小白的朋友们大家好,这期主要为大家带来有关字典的一些实用技巧。上篇笔记通过感人肺腑的老白让大家认识到了字典这么有用的数据类型,这一期让我们看看如何能更好的操作字典。 基础篇 下面我给大家来一个简单的...
摘要:如何根据需要创建简单模型大家好,今天这一期我想和大家分享有关于创建模型的部分,首先让我们来看一个比较常见的场景你每天需要打开个进行相同的操作,各种眼花缭乱的函数后老眼昏花。。。。 Pandas 如何根据需要创建简单模型 大家好,今天这一期我想和大家分享有关于pandas创建模型的部分,首先让我们来看一个比较常见的场景: 你每天需要打开N个excel进行相同的操作,各种眼花缭乱的VBA函...
摘要:下面让我们开始提速假设我们现在的电价是定值,不根据用电时间段来改变,那么中最快的方法那就是采用,这就是一个简单的矢量化操作示范。它基本是在中运行最快的方式。 Pandas 加速 大家好,今天我们来看有关pandas加速的小技巧,不知道大家在刚刚接触pandas的时候有没有听过如下的说法 pandas太慢了,运行要等半天 其实我想说的是,慢不是pandas的错,大家要知道pandas本身...
摘要:基于上的我们还可以实现几个基于的,还是老样子,先让我们创建两个好了,现在我们想要实现两个的,但是条件是通过的和的这样我们也可以得到结果。 Merge, Join, Concat 大家好,我有回来啦,这周更新的有点慢,主要是因为我更新了个人简历哈哈,如果感兴趣的朋友可以去看看哈: 我的主页 个人认为还是很漂亮的~,不得不说,很多时候老外的设计能力还是很强。 好了,有点扯远了,这一期我想和...
阅读 1458·2021-11-25 09:43
阅读 4004·2021-11-15 11:37
阅读 3146·2021-08-17 10:13
阅读 3472·2019-08-30 14:16
阅读 3499·2019-08-26 18:37
阅读 2461·2019-08-26 11:56
阅读 1082·2019-08-26 10:42
阅读 574·2019-08-26 10:39