02. Pandas读取数据
本代码演示:
-
pandas读取纯文本文件
-
读取csv文件
-
读取txt文件
-
pandas读取xlsx格式excel文件
-
pandas读取mysql数据表
In [1]:
import pandas as pd
1、读取纯文本文件
import pandas as pd fpath = "./ratings.csv" ratings = pd.read_csv(fpath) print(ratings.head()) print(ratings.shape) print(ratings.columns) print(ratings.index) print(ratings.dtypes)
1.1 读取CSV,使用默认的标题行、逗号分隔符
In [2]:
fpath = "./datas/ml-latest-small/ratings.csv"
In [3]:
# 使用pd.read_csv读取数据 ratings = pd.read_csv(fpath)
In [4]:
# 查看前几行数据 ratings.head()
Out[4]:
userId | movieId | rating | timestamp | |
---|---|---|---|---|
0 | 1 | 1 | 4.0 | 964982703 |
1 | 1 | 3 | 4.0 | 964981247 |
2 | 1 | 6 | 4.0 | 964982224 |
3 | 1 | 47 | 5.0 | 964983815 |
4 | 1 | 50 | 5.0 | 964982931 |
In [5]:
# 查看数据的形状,返回(行数、列数) ratings.shape
Out[5]:
(100836, 4)
In [6]:
# 查看列名列表 ratings.columns
Out[6]:
Index(['userId', 'movieId', 'rating', 'timestamp'], dtype='object')
In [7]:
# 查看索引列 ratings.index
Out[7]:
RangeIndex(start=0, stop=100836, step=1)
In [8]:
# 查看每列的数据类型 ratings.dtypes
Out[8]:
userId int64 movieId int64 rating float64 timestamp int64 dtype: object
1.2 读取txt文件,自己指定分隔符、列名
In [9]:
fpath = "./datas/crazyant/access_pvuv.txt"
In [10]:
pvuv = pd.read_csv( fpath, sep="\t", header=None, names=['pdate', 'pv', 'uv'] )
In [11]:
pvuv
Out[11]:
pdate | pv | uv | |
---|---|---|---|
0 | 2019-09-10 | 139 | 92 |
1 | 2019-09-09 | 185 | 153 |
2 | 2019-09-08 | 123 | 59 |
3 | 2019-09-07 | 65 | 40 |
4 | 2019-09-06 | 157 | 98 |
5 | 2019-09-05 | 205 | 151 |
6 | 2019-09-04 | 196 | 167 |
7 | 2019-09-03 | 216 | 176 |
8 | 2019-09-02 | 227 | 148 |
9 | 2019-09-01 | 105 | 61 |
2、读取excel文件
In [12]:
fpath = "./datas/crazyant/access_pvuv.xlsx" pvuv = pd.read_excel(fpath)
In [13]:
pvuv
Out[13]:
日期 | PV | UV | |
---|---|---|---|
0 | 2019-09-10 | 139 | 92 |
1 | 2019-09-09 | 185 | 153 |
2 | 2019-09-08 | 123 | 59 |
3 | 2019-09-07 | 65 | 40 |
4 | 2019-09-06 | 157 | 98 |
5 | 2019-09-05 | 205 | 151 |
6 | 2019-09-04 | 196 | 167 |
7 | 2019-09-03 | 216 | 176 |
8 | 2019-09-02 | 227 | 148 |
9 | 2019-09-01 | 105 | 61 |
import pandas as pd fpath = "./access_pvuv.txt" pvuv= pd.read_csv( fpath, sep="\t", header=None, names=['pdate', 'pv', 'uv'] ) print(pvuv)
3、读取MySQL数据库
In [14]:
import pymysql conn = pymysql.connect( host='127.0.0.1', user='root', password='12345678', database='test', charset='utf8' )
In [15]:
mysql_page = pd.read_sql("select * from crazyant_pvuv", con=conn)
In [16]:
mysql_page
Out[16]:
pdate | pv | uv | |
---|---|---|---|
0 | 2019-09-10 | 139 | 92 |
1 | 2019-09-09 | 185 | 153 |
2 | 2019-09-08 | 123 | 59 |
3 | 2019-09-07 | 65 | 40 |
4 | 2019-09-06 | 157 | 98 |
5 | 2019-09-05 | 205 | 151 |
6 | 2019-09-04 | 196 | 167 |
7 | 2019-09-03 | 216 | 176 |
8 | 2019-09-02 | 227 | 148 |
9 | 2019-09-01 | 105 | 61 |
In [ ]:
-
Series
-
DataFrame
-
从DataFrame中查询出Series
In [1]:
import pandas as pd import numpy as np
import pandas as pd import pymysql conn=pymysql.connect( host='127.0.0.1', user='root', password='12345678', database='test', charset='utf8' ) mysql_page=pd.read_sql("select * from crazyant_pvuv",con=conn) print(mysql_page)
1. Series
Series是一种类似于一维数组的对象,它由一组数据(不同数据类型)以及一组与之相关的数据标签(即索引)组成。
1.1 仅有数据列表即可产生最简单的Series
In [2]:
s1 = pd.Series([1,'a',5.2,7])
In [3]:
# 左侧为索引,右侧是数据 s1
Out[3]:
0 1 1 a 2 5.2 3 7 dtype: object
In [4]:
# 获取索引 s1.index
Out[4]:
RangeIndex(start=0, stop=4, step=1)
In [5]:
# 获取数据 s1.values
Out[5]:
array([1, 'a', 5.2, 7], dtype=object)
1.2 创建一个具有标签索引的Series
In [6]:
s2 = pd.Series([1, 'a', 5.2, 7], index=['d','b','a','c'])
In [7]:
s2
Out[7]:
d 1 b a a 5.2 c 7 dtype: object
In [8]:
s2.index
Out[8]:
Index(['d', 'b', 'a', 'c'], dtype='object')
1.3 使用Python字典创建Series
In [9]:
sdata={'Ohio':35000,'Texas':72000,'Oregon':16000,'Utah':5000}
In [10]:
s3=pd.Series(sdata)
In [11]:
s3
Out[11]:
Ohio 35000 Texas 72000 Oregon 16000 Utah 5000 dtype: int64
1.4 根据标签索引查询数据
类似Python的字典dict
In [12]:
s2
Out[12]:
d 1 b a a 5.2 c 7 dtype: object
In [13]:
s2['a']
Out[13]:
5.2
In [14]:
type(s2['a'])
Out[14]:
float
In [15]:
s2[['b','a']]
Out[15]:
b a a 5.2 dtype: object
In [16]:
type(s2[['b','a']])
Out[16]:
pandas.core.series.Series
2. DataFrame
DataFrame是一个表格型的数据结构
-
每列可以是不同的值类型(数值、字符串、布尔值等)
-
既有行索引index,也有列索引columns
-
可以被看做由Series组成的字典
创建dataframe最常用的方法,见02节读取纯文本文件、excel、mysql数据库
2.1 根据多个字典序列创建dataframe
In [17]:
data={ 'state':['Ohio','Ohio','Ohio','Nevada','Nevada'], 'year':[2000,2001,2002,2001,2002], 'pop':[1.5,1.7,3.6,2.4,2.9] } df = pd.DataFrame(data)
In [18]:
df
Out[18]:
state | year | pop | |
---|---|---|---|
0 | Ohio | 2000 | 1.5 |
1 | Ohio | 2001 | 1.7 |
2 | Ohio | 2002 | 3.6 |
3 | Nevada | 2001 | 2.4 |
4 | Nevada | 2002 | 2.9 |
In [19]:
df.dtypes
Out[19]:
state object year int64 pop float64 dtype: object
In [20]:
df.columns
Out[20]:
Index(['state', 'year', 'pop'], dtype='object')
In [21]:
df.index
Out[21]:
RangeIndex(start=0, stop=5, step=1)
3. 从DataFrame中查询出Series
-
如果只查询一行、一列,返回的是pd.Series
-
如果查询多行、多列,返回的是pd.DataFrame
In [22]:
df
Out[22]:
state | year | pop | |
---|---|---|---|
0 | Ohio | 2000 | 1.5 |
1 | Ohio | 2001 | 1.7 |
2 | Ohio | 2002 | 3.6 |
3 | Nevada | 2001 | 2.4 |
4 | Nevada | 2002 | 2.9 |
3.1 查询一列,结果是一个pd.Series
In [23]:
df['year']
Out[23]:
0 2000 1 2001 2 2002 3 2001 4 2002 Name: year, dtype: int64
In [24]:
type(df['year'])
Out[24]:
pandas.core.series.Series
3.2 查询多列,结果是一个pd.DataFrame
In [25]:
df[['year', 'pop']]
Out[25]:
year | pop | |
---|---|---|
0 | 2000 | 1.5 |
1 | 2001 | 1.7 |
2 | 2002 | 3.6 |
3 | 2001 | 2.4 |
4 | 2002 | 2.9 |
In [26]:
type(df[['year', 'pop']])
Out[26]:
pandas.core.frame.DataFrame
3.3 查询一行,结果是一个pd.Series
In [27]:
df.loc[1]
Out[27]:
state Ohio year 2001 pop 1.7 Name: 1, dtype: object
In [28]:
type(df.loc[1])
Out[28]:
pandas.core.series.Series
3.4 查询多行,结果是一个pd.DataFrame
In [29]:
df.loc[1:3]
Out[29]:
state | year | pop | |
---|---|---|---|
1 | Ohio | 2001 | 1.7 |
2 | Ohio | 2002 | 3.6 |
3 | Nevada | 2001 | 2.4 |
In [30]:
type(df.loc[1:3])
Out[30]:
pandas.core.frame.DataFrame
import pandas as pd import numpy as np # 创建一个不带标签的 Series s1 = pd.Series([1, 'a', 5.2, 7]) print(s1) # 输出 s1 的内容 print(s1.index) # 输出 s1 的索引 print(s1.values) # 输出 s1 的值 # 通过指定索引标签创建一个 Series s2 = pd.Series([1, 'a', 5.2, 7], index=['a', 'b', 'c', 'd']) print(s2.index) # 输出 s2 的索引 print(s2) # 输出 s2 的内容 # 使用列表或字典中的数据创建 Series sdata = {'Ohio': 35000, 'Texas': 72000, 'Oregon': 16000, 'Utah': 5000} s3 = pd.Series(sdata) print(s3) # 输出 s3 的内容 # 输出 Series 中的元素及类型信息等 print(s2['a']) # 输出 S2 中 a 对应的元素 print(type(s2['a'])) # 输出 S2 中 a 对应元素的类型 print(s2[['b', 'a']]) # 输出 S2 中 b,a 位置对应的元素 print(type(s2[['a', 'b']])) # 输出 S2 中 b,a 位置对应的元素的类型 # 使用嵌套字典来创建 DataFrame data = { 'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 'year': [2000, 2001, 2002, 2001, 2002], 'pop': [1.5, 1.7, 3.6, 2.4, 2.9] } df = pd.DataFrame(data) print(df.dtypes) # 输出 df 各列的数据类型信息 print(df.columns) # 输出 df 各列名称 print(df.index) # 输出 df 的行索引 print(df) # 输出 df 内容 # 获取 DataFrame 的一部分数据 print(df['year']) # 输出 df 数据中“年份”所在的列 print(type(df['year'])) # 输出 df 数据中“年份”列的数据类型 print(df[['year', 'pop']]) # 输出 df 数据中“年份”和“人口”两列的数据 # 使用 loc 方法访问 DataFrame 中某一行或若干行 print(df.loc[1]) # 输出 df 中 index 为 1 的那一行 print(type(df.loc[1])) # 输出通过 loc 方法取出的 df 的行的数据类型 print(df.loc[1:3]) # 输出从 1 到 3 行(包括边界)所有数据 print(type(df.loc[1:3])) # 输出通过 loc 方法取出的 df 区域块的数据类型
Pandas查询数据
今天没有漂亮的PPT,只有干货!!
Pandas查询数据的几种方法
-
df.loc方法,根据行、列的标签值查询
-
df.iloc方法,根据行、列的数字位置查询
-
df.where方法
-
df.query方法
.loc既能查询,又能覆盖写入,强烈推荐!
Pandas使用df.loc查询数据的方法
-
使用单个label值查询数据
-
使用值列表批量查询
-
使用数值区间进行范围查询
-
使用条件表达式查询
-
调用函数查询
注意
-
以上查询方法,既适用于行,也适用于列
-
注意观察降维dataFrame>Series>值
微信公众号:【蚂蚁学Python】,Python原创免费视频分享
In [23]:
import pandas as pd print(pd.__version__) 1.0.1
0、读取数据
数据为北京2018年全年天气预报 该数据的爬虫教程参见我的Python爬虫系列视频课程
In [2]:
df = pd.read_csv("./datas/beijing_tianqi/beijing_tianqi_2018.csv")
In [3]:
df.head()
Out[3]:
ymd | bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|---|
0 | 2018-01-01 | 3℃ | -6℃ | 晴~多云 | 东北风 | 1-2级 | 59 | 良 | 2 |
1 | 2018-01-02 | 2℃ | -5℃ | 阴~多云 | 东北风 | 1-2级 | 49 | 优 | 1 |
2 | 2018-01-03 | 2℃ | -5℃ | 多云 | 北风 | 1-2级 | 28 | 优 | 1 |
3 | 2018-01-04 | 0℃ | -8℃ | 阴 | 东北风 | 1-2级 | 28 | 优 | 1 |
4 | 2018-01-05 | 3℃ | -6℃ | 多云~晴 | 西北风 | 1-2级 | 50 | 优 | 1 |
In [4]:
# 设定索引为日期,方便按日期筛选 df.set_index('ymd', inplace=True)
In [5]:
# 时间序列见后续课程,本次按字符串处理 df.index
Out[5]:
Index(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04', '2018-01-05', '2018-01-06', '2018-01-07', '2018-01-08', '2018-01-09', '2018-01-10', ... '2018-12-22', '2018-12-23', '2018-12-24', '2018-12-25', '2018-12-26', '2018-12-27', '2018-12-28', '2018-12-29', '2018-12-30', '2018-12-31'], dtype='object', name='ymd', length=365)
In [6]:
df.head()
Out[6]:
bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|
ymd | ||||||||
2018-01-01 | 3℃ | -6℃ | 晴~多云 | 东北风 | 1-2级 | 59 | 良 | 2 |
2018-01-02 | 2℃ | -5℃ | 阴~多云 | 东北风 | 1-2级 | 49 | 优 | 1 |
2018-01-03 | 2℃ | -5℃ | 多云 | 北风 | 1-2级 | 28 | 优 | 1 |
2018-01-04 | 0℃ | -8℃ | 阴 | 东北风 | 1-2级 | 28 | 优 | 1 |
2018-01-05 | 3℃ | -6℃ | 多云~晴 | 西北风 | 1-2级 | 50 | 优 | 1 |
In [7]:
# 替换掉温度的后缀℃ df.loc[:, "bWendu"] = df["bWendu"].str.replace("℃", "").astype('int32') df.loc[:, "yWendu"] = df["yWendu"].str.replace("℃", "").astype('int32')
In [8]:
df.dtypes
Out[8]:
bWendu int32 yWendu int32 tianqi object fengxiang object fengli object aqi int64 aqiInfo object aqiLevel int64 dtype: object
In [9]:
df.head()
Out[9]:
bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|
ymd | ||||||||
2018-01-01 | 3 | -6 | 晴~多云 | 东北风 | 1-2级 | 59 | 良 | 2 |
2018-01-02 | 2 | -5 | 阴~多云 | 东北风 | 1-2级 | 49 | 优 | 1 |
2018-01-03 | 2 | -5 | 多云 | 北风 | 1-2级 | 28 | 优 | 1 |
2018-01-04 | 0 | -8 | 阴 | 东北风 | 1-2级 | 28 | 优 | 1 |
2018-01-05 | 3 | -6 | 多云~晴 | 西北风 | 1-2级 | 50 | 优 | 1 |
1、使用单个label值查询数据
行或者列,都可以只传入单个值,实现精确匹配
In [10]:
# 得到单个值 df.loc['2018-01-03', 'bWendu']
Out[10]:
2
In [11]:
# 得到一个Series df.loc['2018-01-03', ['bWendu', 'yWendu']]
Out[11]:
bWendu 2 yWendu -5 Name: 2018-01-03, dtype: object
2、使用值列表批量查询
In [12]:
# 得到Series df.loc[['2018-01-03','2018-01-04','2018-01-05'], 'bWendu']
Out[12]:
ymd 2018-01-03 2 2018-01-04 0 2018-01-05 3 Name: bWendu, dtype: int32
In [13]:
# 得到DataFrame df.loc[['2018-01-03','2018-01-04','2018-01-05'], ['bWendu', 'yWendu']]
Out[13]:
bWendu | yWendu | |
---|---|---|
ymd | ||
2018-01-03 | 2 | -5 |
2018-01-04 | 0 | -8 |
2018-01-05 | 3 | -6 |
3、使用数值区间进行范围查询
注意:区间既包含开始,也包含结束
In [14]:
# 行index按区间 df.loc['2018-01-03':'2018-01-05', 'bWendu']
Out[14]:
ymd 2018-01-03 2 2018-01-04 0 2018-01-05 3 Name: bWendu, dtype: int32
In [15]:
# 列index按区间 df.loc['2018-01-03', 'bWendu':'fengxiang']
Out[15]:
bWendu 2 yWendu -5 tianqi 多云 fengxiang 北风 Name: 2018-01-03, dtype: object
In [16]:
# 行和列都按区间查询 df.loc['2018-01-03':'2018-01-05', 'bWendu':'fengxiang']
Out[16]:
bWendu | yWendu | tianqi | fengxiang | |
---|---|---|---|---|
ymd | ||||
2018-01-03 | 2 | -5 | 多云 | 北风 |
2018-01-04 | 0 | -8 | 阴 | 东北风 |
2018-01-05 | 3 | -6 | 多云~晴 | 西北风 |
4、使用条件表达式查询
bool列表的长度得等于行数或者列数
简单条件查询,最低温度低于-10度的列表
In [17]:
df.loc[df["yWendu"]<-10, :]
Out[17]:
bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|
ymd | ||||||||
2018-01-23 | -4 | -12 | 晴 | 西北风 | 3-4级 | 31 | 优 | 1 |
2018-01-24 | -4 | -11 | 晴 | 西南风 | 1-2级 | 34 | 优 | 1 |
2018-01-25 | -3 | -11 | 多云 | 东北风 | 1-2级 | 27 | 优 | 1 |
2018-12-26 | -2 | -11 | 晴~多云 | 东北风 | 2级 | 26 | 优 | 1 |
2018-12-27 | -5 | -12 | 多云~晴 | 西北风 | 3级 | 48 | 优 | 1 |
2018-12-28 | -3 | -11 | 晴 | 西北风 | 3级 | 40 | 优 | 1 |
2018-12-29 | -3 | -12 | 晴 | 西北风 | 2级 | 29 | 优 | 1 |
2018-12-30 | -2 | -11 | 晴~多云 | 东北风 | 1级 | 31 | 优 | 1 |
In [18]:
# 观察一下这里的boolean条件 df["yWendu"]<-10
Out[18]:
ymd 2018-01-01 False 2018-01-02 False 2018-01-03 False 2018-01-04 False 2018-01-05 False ... 2018-12-27 True 2018-12-28 True 2018-12-29 True 2018-12-30 True 2018-12-31 False Name: yWendu, Length: 365, dtype: bool
复杂条件查询,查一下我心中的完美天气
注意,组合条件用&符号合并,每个条件判断都得带括号
In [19]:
## 查询最高温度小于30度,并且最低温度大于15度,并且是晴天,并且天气为优的数据 df.loc[(df["bWendu"]<=30) & (df["yWendu"]>=15) & (df["tianqi"]=='晴') & (df["aqiLevel"]==1), :]
Out[19]:
bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|
ymd | ||||||||
2018-08-24 | 30 | 20 | 晴 | 北风 | 1-2级 | 40 | 优 | 1 |
2018-09-07 | 27 | 16 | 晴 | 西北风 | 3-4级 | 22 | 优 | 1 |
我哭,北京好天气这么稀少!!
In [20]:
# 再次观察这里的boolean条件 (df["bWendu"]<=30) & (df["yWendu"]>=15) & (df["tianqi"]=='晴') & (df["aqiLevel"]==1)
Out[20]:
ymd 2018-01-01 False 2018-01-02 False 2018-01-03 False 2018-01-04 False 2018-01-05 False ... 2018-12-27 False 2018-12-28 False 2018-12-29 False 2018-12-30 False 2018-12-31 False Length: 365, dtype: bool
import pandas as pd print(pd.__version__) df = pd.read_csv("./beijing_tianqi_2018.csv") print(df.head()) df.set_index('ymd', inplace=True) print(df.index) print(df.head()) df.loc[:, "bWendu"] = df["bWendu"].str.replace("℃", "").astype("int32") df.loc[:, "yWendu"] = df["yWendu"].str.replace("℃", "").astype("int32") print(df.dtypes) print(df.head()) print(df.loc['2018-01-03','bWendu']) print(df.loc['2018-01-03',['bWendu','yWendu']]) print(df.loc[['2018-01-03','2018-01-04','2018-01-05'],'bWendu']) print(df.loc[['2018-01-03','2018-01-04','2018-01-05'],['bWendu','yWendu']]) print(df.loc['2018-01-03':'2018-01-05','bWendu']) print(df.loc['2018-01-03','bWendu':'fengxiang']) print(df.loc['2018-01-03':'2018-01-05','bWendu':'fengxiang']) print(df.loc[df['yWendu']<10,:]) print(df['yWendu']<-10) print(df.loc[(df["bWendu"] <= 30) & (df["yWendu"] >= 15) & (df["tianqi"] == '晴') & (df["aqiLevel"] == 1), :]) print((df['bWendu'] <= 30) & (df['yWendu'] >= 15) & (df["tianqi"] == '晴') & (df['aqiLevel'] == 1)) print(df.loc[lambda df: (df['bWendu'] <= 30) & (df['yWendu'] >= 15), :]) def query_my_data(df): return df.index.str.startswith('2018-09') & (df['aqiLevel'] == 1) print(df.loc[query_my_data, :])
5、调用函数查询
In [21]:
# 直接写lambda表达式 df.loc[lambda df : (df["bWendu"]<=30) & (df["yWendu"]>=15), :]
Out[21]:
bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|
ymd | ||||||||
2018-04-28 | 27 | 17 | 晴 | 西南风 | 3-4级 | 125 | 轻度污染 | 3 |
2018-04-29 | 30 | 16 | 多云 | 南风 | 3-4级 | 193 | 中度污染 | 4 |
2018-05-04 | 27 | 16 | 晴~多云 | 西南风 | 1-2级 | 86 | 良 | 2 |
2018-05-09 | 29 | 17 | 晴~多云 | 西南风 | 3-4级 | 79 | 良 | 2 |
2018-05-10 | 26 | 18 | 多云 | 南风 | 3-4级 | 118 | 轻度污染 | 3 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
2018-09-15 | 26 | 15 | 多云 | 北风 | 3-4级 | 42 | 优 | 1 |
2018-09-17 | 27 | 17 | 多云~阴 | 北风 | 1-2级 | 37 | 优 | 1 |
2018-09-18 | 25 | 17 | 阴~多云 | 西南风 | 1-2级 | 50 | 优 | 1 |
2018-09-19 | 26 | 17 | 多云 | 南风 | 1-2级 | 52 | 良 | 2 |
2018-09-20 | 27 | 16 | 多云 | 西南风 | 1-2级 | 63 | 良 | 2 |
64 rows × 8 columns
In [22]:
# 编写自己的函数,查询9月份,空气质量好的数据 def query_my_data(df): return df.index.str.startswith("2018-09") & (df["aqiLevel"]==1) df.loc[query_my_data, :]
Out[22]:
bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|
ymd | ||||||||
2018-09-01 | 27 | 19 | 阴~小雨 | 南风 | 1-2级 | 50 | 优 | 1 |
2018-09-04 | 31 | 18 | 晴 | 西南风 | 3-4级 | 24 | 优 | 1 |
2018-09-05 | 31 | 19 | 晴~多云 | 西南风 | 3-4级 | 34 | 优 | 1 |
2018-09-06 | 27 | 18 | 多云~晴 | 西北风 | 4-5级 | 37 | 优 | 1 |
2018-09-07 | 27 | 16 | 晴 | 西北风 | 3-4级 | 22 | 优 | 1 |
2018-09-08 | 27 | 15 | 多云~晴 | 北风 | 1-2级 | 28 | 优 | 1 |
2018-09-15 | 26 | 15 | 多云 | 北风 | 3-4级 | 42 | 优 | 1 |
2018-09-16 | 25 | 14 | 多云~晴 | 北风 | 1-2级 | 29 | 优 | 1 |
2018-09-17 | 27 | 17 | 多云~阴 | 北风 | 1-2级 | 37 | 优 | 1 |
2018-09-18 | 25 | 17 | 阴~多云 | 西南风 | 1-2级 | 50 | 优 | 1 |
2018-09-21 | 25 | 14 | 晴 | 西北风 | 3-4级 | 50 | 优 | 1 |
2018-09-22 | 24 | 13 | 晴 | 西北风 | 3-4级 | 28 | 优 | 1 |
2018-09-23 | 23 | 12 | 晴 | 西北风 | 4-5级 | 28 | 优 | 1 |
2018-09-24 | 23 | 11 | 晴 | 北风 | 1-2级 | 28 | 优 | 1 |
2018-09-25 | 24 | 12 | 晴~多云 | 南风 | 1-2级 | 44 | 优 | 1 |
2018-09-29 | 22 | 11 | 晴 | 北风 | 3-4级 | 21 | 优 | 1 |
2018-09-30 | 19 | 13 | 多云 | 西北风 | 4-5级 | 22 | 优 | 1 |
Pandas怎样新增数据列?
在进行数据分析时,经常需要按照一定条件创建新的数据列,然后进行进一步分析。
-
直接赋值
-
df.apply方法
-
df.assign方法
-
按条件选择分组分别赋值 微信公众号:蚂蚁学Python
In [1]:
import pandas as pd
0、读取csv数据到dataframe
In [2]:
fpath = "./datas/beijing_tianqi/beijing_tianqi_2018.csv" df = pd.read_csv(fpath)
In [3]:
df.head()
Out[3]:
ymd | bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|---|
0 | 2018-01-01 | 3℃ | -6℃ | 晴~多云 | 东北风 | 1-2级 | 59 | 良 | 2 |
1 | 2018-01-02 | 2℃ | -5℃ | 阴~多云 | 东北风 | 1-2级 | 49 | 优 | 1 |
2 | 2018-01-03 | 2℃ | -5℃ | 多云 | 北风 | 1-2级 | 28 | 优 | 1 |
3 | 2018-01-04 | 0℃ | -8℃ | 阴 | 东北风 | 1-2级 | 28 | 优 | 1 |
4 | 2018-01-05 | 3℃ | -6℃ | 多云~晴 | 西北风 | 1-2级 | 50 | 优 | 1 |
1、直接赋值的方法
实例:清理温度列,变成数字类型
In [4]:
# 替换掉温度的后缀℃ df.loc[:, "bWendu"] = df["bWendu"].str.replace("℃", "").astype('int32') df.loc[:, "yWendu"] = df["yWendu"].str.replace("℃", "").astype('int32')
In [6]:
df.head()
Out[6]:
ymd | bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|---|
0 | 2018-01-01 | 3 | -6 | 晴~多云 | 东北风 | 1-2级 | 59 | 良 | 2 |
1 | 2018-01-02 | 2 | -5 | 阴~多云 | 东北风 | 1-2级 | 49 | 优 | 1 |
2 | 2018-01-03 | 2 | -5 | 多云 | 北风 | 1-2级 | 28 | 优 | 1 |
3 | 2018-01-04 | 0 | -8 | 阴 | 东北风 | 1-2级 | 28 | 优 | 1 |
4 | 2018-01-05 | 3 | -6 | 多云~晴 | 西北风 | 1-2级 | 50 | 优 | 1 |
实例:计算温差
In [9]:
# 注意,df["bWendu"]其实是一个Series,后面的减法返回的是Series df.loc[:, "wencha"] = df["bWendu"] - df["yWendu"]
In [10]:
df.head()
Out[10]:
ymd | bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | wencha | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 2018-01-01 | 3 | -6 | 晴~多云 | 东北风 | 1-2级 | 59 | 良 | 2 | 9 |
1 | 2018-01-02 | 2 | -5 | 阴~多云 | 东北风 | 1-2级 | 49 | 优 | 1 | 7 |
2 | 2018-01-03 | 2 | -5 | 多云 | 北风 | 1-2级 | 28 | 优 | 1 | 7 |
3 | 2018-01-04 | 0 | -8 | 阴 | 东北风 | 1-2级 | 28 | 优 | 1 | 8 |
4 | 2018-01-05 | 3 | -6 | 多云~晴 | 西北风 | 1-2级 | 50 | 优 | 1 | 9 |
2、df.apply方法
Apply a function along an axis of the DataFrame.
Objects passed to the function are Series objects whose index is either the DataFrame’s index (axis=0) or the DataFrame’s columns (axis=1).
实例:添加一列温度类型:
-
如果最高温度大于33度就是高温
-
低于-10度是低温
-
否则是常温
In [11]:
def get_wendu_type(x): if x["bWendu"] > 33: return '高温' if x["yWendu"] < -10: return '低温' return '常温' # 注意需要设置axis==1,这是series的index是columns df.loc[:, "wendu_type"] = df.apply(get_wendu_type, axis=1)
In [12]:
# 查看温度类型的计数 df["wendu_type"].value_counts()
Out[12]:
常温 328 高温 29 低温 8 Name: wendu_type, dtype: int64
3、df.assign方法
Assign new columns to a DataFrame.
Returns a new object with all original columns in addition to new ones.
实例:将温度从摄氏度变成华氏度
In [13]:
# 可以同时添加多个新的列 df.assign( yWendu_huashi = lambda x : x["yWendu"] * 9 / 5 + 32, # 摄氏度转华氏度 bWendu_huashi = lambda x : x["bWendu"] * 9 / 5 + 32 )
Out[13]:
ymd | bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | wencha | wendu_type | yWendu_huashi | bWendu_huashi | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2018-01-01 | 3 | -6 | 晴~多云 | 东北风 | 1-2级 | 59 | 良 | 2 | 9 | 常温 | 21.2 | 37.4 |
1 | 2018-01-02 | 2 | -5 | 阴~多云 | 东北风 | 1-2级 | 49 | 优 | 1 | 7 | 常温 | 23.0 | 35.6 |
2 | 2018-01-03 | 2 | -5 | 多云 | 北风 | 1-2级 | 28 | 优 | 1 | 7 | 常温 | 23.0 | 35.6 |
3 | 2018-01-04 | 0 | -8 | 阴 | 东北风 | 1-2级 | 28 | 优 | 1 | 8 | 常温 | 17.6 | 32.0 |
4 | 2018-01-05 | 3 | -6 | 多云~晴 | 西北风 | 1-2级 | 50 | 优 | 1 | 9 | 常温 | 21.2 | 37.4 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
360 | 2018-12-27 | -5 | -12 | 多云~晴 | 西北风 | 3级 | 48 | 优 | 1 | 7 | 低温 | 10.4 | 23.0 |
361 | 2018-12-28 | -3 | -11 | 晴 | 西北风 | 3级 | 40 | 优 | 1 | 8 | 低温 | 12.2 | 26.6 |
362 | 2018-12-29 | -3 | -12 | 晴 | 西北风 | 2级 | 29 | 优 | 1 | 9 | 低温 | 10.4 | 26.6 |
363 | 2018-12-30 | -2 | -11 | 晴~多云 | 东北风 | 1级 | 31 | 优 | 1 | 9 | 低温 | 12.2 | 28.4 |
364 | 2018-12-31 | -2 | -10 | 多云 | 东北风 | 1级 | 56 | 良 | 2 | 8 | 常温 | 14.0 | 28.4 |
365 rows × 13 columns
4、按条件选择分组分别赋值
按条件先选择数据,然后对这部分数据赋值新列 实例:高低温差大于10度,则认为温差大
In [14]:
# 先创建空列(这是第一种创建新列的方法) df['wencha_type'] = '' df.loc[df["bWendu"]-df["yWendu"]>10, "wencha_type"] = "温差大" df.loc[df["bWendu"]-df["yWendu"]<=10, "wencha_type"] = "温差正常"
In [15]:
df["wencha_type"].value_counts()
Out[15]:
温差正常 187 温差大 178 Name: wencha_type, dtype: int64
import pandas as pd df = pd.read_csv("./beijing_tianqi_2018.csv") print(df.head()) df.loc[:, 'bWendu'] = df['bWendu'].str.replace('℃', '').astype('int32') df.loc[:, 'yWendu'] = df['yWendu'].str.replace('℃', '').astype('int32') print(df.head()) df.loc[:, 'wendu'] = df['bWendu'] - df['yWendu'] print(df.head()) def get_wendu_type(x): if x['bWendu'] > 33: return '高温' if x['yWendu'] < -10: return '低温' return '常温' df.loc[:, 'wendu_type'] = df.apply(get_wendu_type, axis=1) print(df['wendu_type'].value_counts()) df.assign( yWendu_huashi=lambda x: x['yWendu'] * 9 / 5 + 32, bWendu_huashi=lambda x: x['bWendu'] * 9 / 5 + 32 ) print(df.assign()) df['wendu_type']='' df.loc[df['bWendu']-df['yWendu']>10,'wencha_type']='温差很大' df.loc[df['bWendu']-df['yWendu']<=10,'wencha_type']='温差正常' print(df['wencha_type'].value_counts())
Pandas数据排序
Series的排序: Series.sort_values(ascending=True, inplace=False) 参数说明:
-
ascending:默认为True升序排序,为False降序排序
-
inplace:是否修改原始Series
DataFrame的排序: DataFrame.sort_values(by, ascending=True, inplace=False) 参数说明:
-
by:字符串或者List<字符串>,单列排序或者多列排序
-
ascending:bool或者List,升序还是降序,如果是list对应by的多列
-
inplace:是否修改原始DataFrame
In [2]:
import pandas as pd
0、读取数据
In [3]:
fpath = "./datas/beijing_tianqi/beijing_tianqi_2018.csv" df = pd.read_csv(fpath) # 替换掉温度的后缀℃ df.loc[:, "bWendu"] = df["bWendu"].str.replace("℃", "").astype('int32') df.loc[:, "yWendu"] = df["yWendu"].str.replace("℃", "").astype('int32')
In [4]:
df.head()
Out[4]:
ymd | bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|---|
0 | 2018-01-01 | 3 | -6 | 晴~多云 | 东北风 | 1-2级 | 59 | 良 | 2 |
1 | 2018-01-02 | 2 | -5 | 阴~多云 | 东北风 | 1-2级 | 49 | 优 | 1 |
2 | 2018-01-03 | 2 | -5 | 多云 | 北风 | 1-2级 | 28 | 优 | 1 |
3 | 2018-01-04 | 0 | -8 | 阴 | 东北风 | 1-2级 | 28 | 优 | 1 |
4 | 2018-01-05 | 3 | -6 | 多云~晴 | 西北风 | 1-2级 | 50 | 优 | 1 |
1、Series的排序
In [5]:
df["aqi"].sort_values()
Out[5]:
271 21 281 21 249 22 272 22 301 22 ... 317 266 71 287 91 287 72 293 86 387 Name: aqi, Length: 365, dtype: int64
In [6]:
df["aqi"].sort_values(ascending=False)
Out[6]:
86 387 72 293 91 287 71 287 317 266 ... 301 22 272 22 249 22 281 21 271 21 Name: aqi, Length: 365, dtype: int64
In [8]:
df["tianqi"].sort_values()
Out[8]:
225 中雨~小雨 230 中雨~小雨 197 中雨~雷阵雨 196 中雨~雷阵雨 112 多云 ... 191 雷阵雨~大雨 219 雷阵雨~阴 335 雾~多云 353 霾 348 霾 Name: tianqi, Length: 365, dtype: object
2、DataFrame的排序
2.1 单列排序
In [9]:
df.sort_values(by="aqi")
Out[9]:
ymd | bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|---|
271 | 2018-09-29 | 22 | 11 | 晴 | 北风 | 3-4级 | 21 | 优 | 1 |
281 | 2018-10-09 | 15 | 4 | 多云~晴 | 西北风 | 4-5级 | 21 | 优 | 1 |
249 | 2018-09-07 | 27 | 16 | 晴 | 西北风 | 3-4级 | 22 | 优 | 1 |
272 | 2018-09-30 | 19 | 13 | 多云 | 西北风 | 4-5级 | 22 | 优 | 1 |
301 | 2018-10-29 | 15 | 3 | 晴 | 北风 | 3-4级 | 22 | 优 | 1 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
317 | 2018-11-14 | 13 | 5 | 多云 | 南风 | 1-2级 | 266 | 重度污染 | 5 |
71 | 2018-03-13 | 17 | 5 | 晴~多云 | 南风 | 1-2级 | 287 | 重度污染 | 5 |
91 | 2018-04-02 | 26 | 11 | 多云 | 北风 | 1-2级 | 287 | 重度污染 | 5 |
72 | 2018-03-14 | 15 | 6 | 多云~阴 | 东北风 | 1-2级 | 293 | 重度污染 | 5 |
86 | 2018-03-28 | 25 | 9 | 多云~晴 | 东风 | 1-2级 | 387 | 严重污染 | 6 |
365 rows × 9 columns
In [10]:
df.sort_values(by="aqi", ascending=False)
Out[10]:
ymd | bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|---|
86 | 2018-03-28 | 25 | 9 | 多云~晴 | 东风 | 1-2级 | 387 | 严重污染 | 6 |
72 | 2018-03-14 | 15 | 6 | 多云~阴 | 东北风 | 1-2级 | 293 | 重度污染 | 5 |
71 | 2018-03-13 | 17 | 5 | 晴~多云 | 南风 | 1-2级 | 287 | 重度污染 | 5 |
91 | 2018-04-02 | 26 | 11 | 多云 | 北风 | 1-2级 | 287 | 重度污染 | 5 |
317 | 2018-11-14 | 13 | 5 | 多云 | 南风 | 1-2级 | 266 | 重度污染 | 5 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
249 | 2018-09-07 | 27 | 16 | 晴 | 西北风 | 3-4级 | 22 | 优 | 1 |
301 | 2018-10-29 | 15 | 3 | 晴 | 北风 | 3-4级 | 22 | 优 | 1 |
272 | 2018-09-30 | 19 | 13 | 多云 | 西北风 | 4-5级 | 22 | 优 | 1 |
271 | 2018-09-29 | 22 | 11 | 晴 | 北风 | 3-4级 | 21 | 优 | 1 |
281 | 2018-10-09 | 15 | 4 | 多云~晴 | 西北风 | 4-5级 | 21 | 优 | 1 |
365 rows × 9 columns
2.2 多列排序
In [11]:
# 按空气质量等级、最高温度排序,默认升序 df.sort_values(by=["aqiLevel", "bWendu"])
Out[11]:
ymd | bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|---|
360 | 2018-12-27 | -5 | -12 | 多云~晴 | 西北风 | 3级 | 48 | 优 | 1 |
22 | 2018-01-23 | -4 | -12 | 晴 | 西北风 | 3-4级 | 31 | 优 | 1 |
23 | 2018-01-24 | -4 | -11 | 晴 | 西南风 | 1-2级 | 34 | 优 | 1 |
340 | 2018-12-07 | -4 | -10 | 晴 | 西北风 | 3级 | 33 | 优 | 1 |
21 | 2018-01-22 | -3 | -10 | 小雪~多云 | 东风 | 1-2级 | 47 | 优 | 1 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
71 | 2018-03-13 | 17 | 5 | 晴~多云 | 南风 | 1-2级 | 287 | 重度污染 | 5 |
90 | 2018-04-01 | 25 | 11 | 晴~多云 | 南风 | 1-2级 | 218 | 重度污染 | 5 |
91 | 2018-04-02 | 26 | 11 | 多云 | 北风 | 1-2级 | 287 | 重度污染 | 5 |
85 | 2018-03-27 | 27 | 11 | 晴 | 南风 | 1-2级 | 243 | 重度污染 | 5 |
86 | 2018-03-28 | 25 | 9 | 多云~晴 | 东风 | 1-2级 | 387 | 严重污染 | 6 |
365 rows × 9 columns
In [12]:
# 两个字段都是降序 df.sort_values(by=["aqiLevel", "bWendu"], ascending=False)
Out[12]:
ymd | bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|---|
86 | 2018-03-28 | 25 | 9 | 多云~晴 | 东风 | 1-2级 | 387 | 严重污染 | 6 |
85 | 2018-03-27 | 27 | 11 | 晴 | 南风 | 1-2级 | 243 | 重度污染 | 5 |
91 | 2018-04-02 | 26 | 11 | 多云 | 北风 | 1-2级 | 287 | 重度污染 | 5 |
90 | 2018-04-01 | 25 | 11 | 晴~多云 | 南风 | 1-2级 | 218 | 重度污染 | 5 |
71 | 2018-03-13 | 17 | 5 | 晴~多云 | 南风 | 1-2级 | 287 | 重度污染 | 5 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
362 | 2018-12-29 | -3 | -12 | 晴 | 西北风 | 2级 | 29 | 优 | 1 |
22 | 2018-01-23 | -4 | -12 | 晴 | 西北风 | 3-4级 | 31 | 优 | 1 |
23 | 2018-01-24 | -4 | -11 | 晴 | 西南风 | 1-2级 | 34 | 优 | 1 |
340 | 2018-12-07 | -4 | -10 | 晴 | 西北风 | 3级 | 33 | 优 | 1 |
360 | 2018-12-27 | -5 | -12 | 多云~晴 | 西北风 | 3级 | 48 | 优 | 1 |
365 rows × 9 columns
In [13]:
# 分别指定升序和降序 df.sort_values(by=["aqiLevel", "bWendu"], ascending=[True, False])
Out[13]:
ymd | bWendu | yWendu | tianqi | fengxiang | fengli | aqi | aqiInfo | aqiLevel | |
---|---|---|---|---|---|---|---|---|---|
178 | 2018-06-28 | 35 | 24 | 多云~晴 | 北风 | 1-2级 | 33 | 优 | 1 |
149 | 2018-05-30 | 33 | 18 | 晴 | 西风 | 1-2级 | 46 | 优 | 1 |
206 | 2018-07-26 | 33 | 25 | 多云~雷阵雨 | 东北风 | 1-2级 | 40 | 优 | 1 |
158 | 2018-06-08 | 32 | 19 | 多云~雷阵雨 | 西南风 | 1-2级 | 43 | 优 | 1 |
205 | 2018-07-25 | 32 | 25 | 多云 | 北风 | 1-2级 | 28 | 优 | 1 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
317 | 2018-11-14 | 13 | 5 | 多云 | 南风 | 1-2级 | 266 | 重度污染 | 5 |
329 | 2018-11-26 | 10 | 0 | 多云 | 东南风 | 1级 | 245 | 重度污染 | 5 |
335 | 2018-12-02 | 9 | 2 | 雾~多云 | 东北风 | 1级 | 234 | 重度污染 | 5 |
57 | 2018-02-27 | 7 | 0 | 阴 | 东风 | 1-2级 | 220 | 重度污染 | 5 |
86 | 2018-03-28 | 25 | 9 | 多云~晴 | 东风 | 1-2级 | 387 | 严重污染 | 6 |
365 rows × 9 columns
import pandas as pd df=pd.read_csv('./beijing_tianqi_2018.csv') df.loc[:,'bWendu']=df['bWendu'].str.replace('℃','').astype('int32') df.loc[:,'yWendu']=df['yWendu'].str.replace('℃','').astype('int32') print(df.head()) print(df['aqi'].sort_values()) print(df['aqi'].sort_values(ascending=False)) print(df['tianqi'].sort_values()) print(df.sort_values(by='aqi')) print(df.sort_values(by='aqi',ascending=False)) print(df.sort_values(by=['aqiLevel','bWendu'])) print(df.sort_values(by=['aqiLevel','bWendu'],ascending=False)) print(df.sort_values(by=['aqiLevel','bWendu'],ascending=[True,False]))