import numpy as np
import pandas as pd
import matplotlib. pyplot as plt
df1 = pd. DataFrame( np. arange( 1000 , 1100 , 4 ) . reshape( 5 , 5 ) , index= [ 'a' + str ( i) for i in range ( 5 ) ] , columns= [ 'b' + str ( j) for j in range ( 5 ) ] )
df1
b0 b1 b2 b3 b4 a0 1000 1004 1008 1012 1016 a1 1020 1024 1028 1032 1036 a2 1040 1044 1048 1052 1056 a3 1060 1064 1068 1072 1076 a4 1080 1084 1088 1092 1096
df2 = pd. Series( [ 1 , 2 , 3 , np. nan, 5 ] , index= list ( 'abcde' ) )
df2
a 1.0
b 2.0
c 3.0
d NaN
e 5.0
dtype: float64
使用传递的numpy数组创建数据帧,并使用日期索引和标记列.
dates = pd. date_range( '20190524' , periods= 6 )
dates
print ( '-' * 30 )
df3 = pd. DataFrame( np. random. randn( 6 , 4 ) , index= dates, columns= list ( 'ABCD' ) )
df3
------------------------------
A B C D 2019-05-24 -0.860206 -0.549105 -1.357905 -0.847048 2019-05-25 1.913799 -0.655915 -0.638752 -0.459323 2019-05-26 0.249178 -1.658453 -2.278093 -0.745429 2019-05-27 0.452118 0.527087 -0.298735 -1.872822 2019-05-28 -1.472450 0.124642 1.554257 -0.085878 2019-05-29 -2.175467 -0.611948 -0.062950 -0.709390
使用传递的可转换序列的字典对象创建数据帧.
df4 = pd. DataFrame( {
'id' : np. arange( 4 ) ,
'date' : pd. Timestamp( '20190524' ) ,
'type' : pd. Series( 1 , index= list ( range ( 4 ) ) , dtype= 'float32' ) ,
'D' : np. array( [ 3 ] * 4 , dtype= 'int32' ) ,
'E' : pd. Categorical( [ "test" , "train" , "test" , "train" ] ) ,
'F' : 'foo'
} )
df4
id date type D E F 0 0 2019-05-24 1.0 3 test foo 1 1 2019-05-24 1.0 3 train foo 2 2 2019-05-24 1.0 3 test foo 3 3 2019-05-24 1.0 3 train foo
单看index, columns, values
df4. index, df4. columns
(Int64Index([0, 1, 2, 3], dtype='int64'),
Index(['id', 'date', 'type', 'D', 'E', 'F'], dtype='object'))
df3. values
array([[-0.86020569, -0.5491055 , -1.3579045 , -0.84704786],
[ 1.91379872, -0.65591487, -0.63875153, -0.4593228 ],
[ 0.24917803, -1.65845292, -2.27809285, -0.74542856],
[ 0.45211825, 0.52708701, -0.29873468, -1.87282174],
[-1.47245001, 0.12464238, 1.55425716, -0.08587762],
[-2.17546674, -0.61194779, -0.06294959, -0.70938972]])
显示数据快速统计摘要
df3. describe( )
A B C D count 6.000000 6.000000 6.000000 6.000000 mean -0.315505 -0.470615 -0.513696 -0.786648 std 1.481390 0.751155 1.293618 0.598216 min -2.175467 -1.658453 -2.278093 -1.872822 25% -1.319389 -0.644923 -1.178116 -0.821643 50% -0.305514 -0.580527 -0.468743 -0.727409 75% 0.401383 -0.043795 -0.121896 -0.521840 max 1.913799 0.527087 1.554257 -0.085878
df4. describe( )
id type D count 4.000000 4.0 4.0 mean 1.500000 1.0 3.0 std 1.290994 0.0 0.0 min 0.000000 1.0 3.0 25% 0.750000 1.0 3.0 50% 1.500000 1.0 3.0 75% 2.250000 1.0 3.0 max 3.000000 1.0 3.0
转置
df4. T
0 1 2 3 id 0 1 2 3 date 2019-05-24 00:00:00 2019-05-24 00:00:00 2019-05-24 00:00:00 2019-05-24 00:00:00 type 1 1 1 1 D 3 3 3 3 E test train test train F foo foo foo foo
按值排序
df3. sort_values( by= 'B' )
A B C D 2019-05-26 0.249178 -1.658453 -2.278093 -0.745429 2019-05-25 1.913799 -0.655915 -0.638752 -0.459323 2019-05-29 -2.175467 -0.611948 -0.062950 -0.709390 2019-05-24 -0.860206 -0.549105 -1.357905 -0.847048 2019-05-28 -1.472450 0.124642 1.554257 -0.085878 2019-05-27 0.452118 0.527087 -0.298735 -1.872822
按轴排序
df3. sort_index( axis= 1 , ascending= False )
D C B A 2019-05-24 -0.847048 -1.357905 -0.549105 -0.860206 2019-05-25 -0.459323 -0.638752 -0.655915 1.913799 2019-05-26 -0.745429 -2.278093 -1.658453 0.249178 2019-05-27 -1.872822 -0.298735 0.527087 0.452118 2019-05-28 -0.085878 1.554257 0.124642 -1.472450 2019-05-29 -0.709390 -0.062950 -0.611948 -2.175467
选择-按标签选择 df.loc[]
print ( df3[ 'A' ] )
print ( '-' * 30 )
print ( df4[ 'E' ] )
print ( '-' * 30 )
print ( df3[ 1 : 3 ] )
print ( '-' * 30 )
print ( df3[ '20190524' : '20190525' ] )
2019-05-24 -0.860206
2019-05-25 1.913799
2019-05-26 0.249178
2019-05-27 0.452118
2019-05-28 -1.472450
2019-05-29 -2.175467
Freq: D, Name: A, dtype: float64
------------------------------
0 test
1 train
2 test
3 train
Name: E, dtype: category
Categories (2, object): [test, train]
------------------------------
A B C D
2019-05-25 1.913799 -0.655915 -0.638752 -0.459323
2019-05-26 0.249178 -1.658453 -2.278093 -0.745429
------------------------------
A B C D
2019-05-24 -0.860206 -0.549105 -1.357905 -0.847048
2019-05-25 1.913799 -0.655915 -0.638752 -0.459323
dates = pd. date_range( '20130101' , periods= 6 )
df = pd. DataFrame( np. arange( 1 , 25 ) . reshape( 6 , 4 ) , index= dates, columns= list ( 'ABCD' ) )
df
A B C D 2013-01-01 1 2 3 4 2013-01-02 5 6 7 8 2013-01-03 9 10 11 12 2013-01-04 13 14 15 16 2013-01-05 17 18 19 20 2013-01-06 21 22 23 24
print ( df. loc[ dates[ 0 ] ] )
A 1
B 2
C 3
D 4
Name: 2013-01-01 00:00:00, dtype: int32
df. loc[ : , [ 'A' , 'B' ] ]
A B 2013-01-01 1 2 2013-01-02 5 6 2013-01-03 9 10 2013-01-04 13 14 2013-01-05 17 18 2013-01-06 21 22
df. loc[ '20130102' : '20130104' , [ 'A' , 'B' ] ]
A B 2013-01-02 5 6 2013-01-03 9 10 2013-01-04 13 14
df. loc[ '20130102' , [ 'A' , 'B' ] ]
A 5
B 6
Name: 2013-01-02 00:00:00, dtype: int32
print ( df. loc[ dates[ 4 ] , 'C' ] )
print ( df. at[ dates[ 4 ] , 'C' ] )
19
19
选择-按位置选择 df.iloc[]
df. iloc[ 3 ]
A 13
B 14
C 15
D 16
Name: 2013-01-04 00:00:00, dtype: int32
df. iloc[ 3 : 5 , 1 : 3 ]
B C 2013-01-04 14 15 2013-01-05 18 19
df. iloc[ [ 1 , 2 , 2 , 4 ] , [ 0 , 2 ] ]
A C 2013-01-02 5 7 2013-01-03 9 11 2013-01-03 9 11 2013-01-05 17 19
df. iloc[ [ 3 for i in range ( 5 ) ] , [ 0 , 2 ] ]
A C 2013-01-04 13 15 2013-01-04 13 15 2013-01-04 13 15 2013-01-04 13 15 2013-01-04 13 15
------------------------学习蚂蚁 pandas----------------------
快速开始-基本使用
import pandas as pd
fpath = './datas/ml-latest-small/ratings.csv'
ratings = pd. read_csv( fpath)
ratings. head( )
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
ratings. shape
(100836, 4)
ratings. columns
Index(['userId', 'movieId', 'rating', 'timestamp'], dtype='object')
ratings. index
RangeIndex(start=0, stop=100836, step=1)
ratings. dtypes
userId int64
movieId int64
rating float64
timestamp int64
dtype: object
1、读取 txt 文件
path1 = './datas/crazyant/access_pvuv.txt'
df1 = pd. read_csv(
path1,
sep= '\t' ,
header= None ,
names= [ 'pdata' , 'pv' , 'uv' ]
)
df1
pdata 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
读取 excel 文件
path2 = './datas/crazyant/access_pvuv.xlsx'
df2 = pd. read_excel( path2)
df2
日期 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
读取 sql 数据库数据
import pymysql
conn = pymysql. connect(
host= '127.0.0.1' ,
user= 'root' ,
password= 'root' ,
database= 'stock' ,
charset= 'utf8'
)
df_sql = pd. read_sql( 'select * from k_goods' , conn)
df_sql
ID PRODUCTNO PRODUCTNAME PRODUCTTYPE PRODUCTSTANDARD UNIT PRICE REMARK 0 1 pdno_0001 计算器 桌面文具 00 个 20 None 1 2 pdno_0002 回形针 桌面文具 00 个 5 None 2 3 pdno_0003 中性笔 桌面文具 00 支 5 None 3 4 pdno_0004 复印纸 纸制品 00 盒 10 None 4 5 pdno_0005 账本 纸制品 00 本 2 None 5 6 pdno_0006 拖布 办公生活用品 00 个 20 None 6 7 pdno_0007 小蜜蜂扩音器 授课设备 00 个 25 None 7 8 pdno_0008 纸杯 办公生活用品 00 个 5 None 8 9 pdno_0009 白板 桌面文具 00 块 50 None 9 10 pdno_0010 软面炒 纸制品 00 本 1 None 10 11 pdno_0011 双面胶 桌面文具 00 个 2 None 11 12 pdno_0012 文件夹 桌面文具 00 把 3 None 12 13 pdno_0013 剪刀 文件管理用品 00 个 8 None 13 14 pdno_0014 档案盒 文件管理用品 00 个 10 None 14 15 pdno_0015 电脑 办公集写 00 个 2000 None
pandas 数据集结构
Series DataFrame 从DataFrame中查询出Series
Series 序列/一维/字典
给定values列表创建Series,默认 index 是range序列
s1 = pd. Series( [ 1 , 'a' , 5.2 , 7 ] )
s1
0 1
1 a
2 5.2
3 7
dtype: object
s1. index
RangeIndex(start=0, stop=4, step=1)
s1. values
array([1, 'a', 5.2, 7], dtype=object)
给定 values列表和index列表创建Series
s21 = pd. Series( range ( 5 ) , index= [ 'a' , 'b' , 'c' , 'd' , 'e' ] )
s22 = pd. Series( [ x - 2 for x in range ( 5 , 14 , 2 ) ] , index= [ 'a' , 'b' , 'c' , 'd' , 'e' ] )
s23 = pd. Series( [ 1 , 'a' , 5.2 , 7 , 0.14 ] , [ 'a' , 'b' , 'c' , 'd' , 'e' ] )
print ( s21)
print ( s22)
print ( s23)
a 0
b 1
c 2
d 3
e 4
dtype: int64
a 3
b 5
c 7
d 9
e 11
dtype: int64
a 1
b a
c 5.2
d 7
e 0.14
dtype: object
使用字典创建 Series
sdata= {
'Ohio' : 35000 ,
'Texas' : 72000 ,
'Oregon' : 16000 ,
'Utah' : 5000
}
s3= pd. Series( sdata)
s3
Ohio 35000
Texas 72000
Oregon 16000
Utah 5000
dtype: int64
根据索引查询数据
print ( s3[ 'Ohio' ] , '\n' )
print ( s3[ [ 'Ohio' , 'Texas' ] ] , '\n' )
print ( s3[ 'Ohio' : 'Utah' ] )
35000
Ohio 35000
Texas 72000
dtype: int64
Ohio 35000
Texas 72000
Oregon 16000
Utah 5000
dtype: int64
DataFrame 表格/二维/数据表
2. DataFrame
DataFrame是一个表格型的数据结构
每列可以是不同的值类型(数值、字符串、布尔值等) 既有行索引index,也有列索引columns 可以被看做由Series组成的字典
创建dataframe最常用的方法,见02节读取纯文本文件、excel、mysql数据库
根据嵌套的字典创建DataFrame 类似与golang 的 map[string][]interface{}
data= {
'state' : [ 'Ohio' , 'Ohio' , 'Ohio' , 'Nevada' , 'Nevada' ] ,
'year' : [ 2000 , 2001 , 2002 , 2001 , 2002 ] ,
'pop' : [ 1.5 , 1.7 , 3.6 , 2.4 , 2.9 ]
}
df3 = pd. DataFrame( data)
df3
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
df3. columns
Index(['state', 'year', 'pop'], dtype='object')
df3. index
RangeIndex(start=0, stop=5, step=1)
df3. shape
(5, 3)
df3. dtypes
state object
year int64
pop float64
dtype: object
df3. values
array([['Ohio', 2000, 1.5],
['Ohio', 2001, 1.7],
['Ohio', 2002, 3.6],
['Nevada', 2001, 2.4],
['Nevada', 2002, 2.9]], dtype=object)
从DataFrame中查询出Series
如果只查询一行、一列,返回的是pd.Series 如果查询多行、多列,返回的是pd.DataFrame
df3[ 'year' ]
0 2000
1 2001
2 2002
3 2001
4 2002
Name: year, dtype: int64
df3[ [ 'year' , 'pop' ] ]
year pop 0 2000 1.5 1 2001 1.7 2 2002 3.6 3 2001 2.4 4 2002 2.9
df3. loc[ 1 ]
state Ohio
year 2001
pop 1.7
Name: 1, dtype: object
df3. loc[ [ 1 : 3 ] ]
df3. loc[ [ 1 , 3 ] ]
state year pop 1 Ohio 2001 1.7 3 Nevada 2001 2.4
pandas 数据查询
Pandas查询数据的几种方法
df.loc方法,根据行、列的标签值查询 df.iloc方法,根据行、列的数字位置查询 df.where方法 df.query方法
.loc既能查询,又能覆盖写入,强烈推荐!
Pandas使用df.loc查询数据的方法
使用单个label值查询数据 使用值列表批量查询 使用数值区间进行范围查询 使用条件表达式查询 调用函数查询
注意
以上查询方法,既适用于行,也适用于列 注意观察降维dataFrame>Series>值
0、读取数据
数据为北京2018年全年天气预报 该数据的爬虫教程参见我的Python爬虫系列视频课程
dff = pd. read_csv( './datas/beijing_tianqi/beijing_tianqi_2018.csv' )
dff. head( )
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
dff. set_index( 'ymd' , inplace= True )
dff. head( )
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
dff. loc[ : , "bWendu" ] = dff[ "bWendu" ] . str . replace( "℃" , "" ) . astype( 'int32' )
dff. loc[ : , "yWendu" ] = dff[ "yWendu" ] . str . replace( "℃" , "" ) . astype( 'int32' )
dff. head( )
bWendu int32
yWendu int32
tianqi object
fengxiang object
fengli object
aqi int64
aqiInfo object
aqiLevel int64
dtype: object
dff. head( )
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值查询数据
行或者列,都可以只传入单个值,实现精确匹配
dff. loc[ '2018-01-03' , 'bWendu' ]
2
dff. loc[ '2018-01-03' , [ 'bWendu' , 'yWendu' ] ]
bWendu 2
yWendu -5
Name: 2018-01-03, dtype: object
2、使用值列表批量查询
df. loc[ [ '2018-01-03' , '2018-01-04' , '2018-01-05' ] , 'bWendu' ]
bWendu 2
yWendu -5
Name: 2018-01-03, dtype: object
dff. loc[ [ '2018-01-03' , '2018-01-04' , '2018-01-05' ] , [ 'bWendu' , 'yWendu' ] ]
bWendu yWendu ymd 2018-01-03 2 -5 2018-01-04 0 -8 2018-01-05 3 -6
3、使用数值区间进行范围查询
注意:区间既包含开始,也包含结束
dff. loc[ '2018-01-03' : '2018-01-05' , 'bWendu' ]
ymd
2018-01-03 2
2018-01-04 0
2018-01-05 3
Name: bWendu, dtype: int32
dff. loc[ '2018-01-03' , 'bWendu' : 'fengxiang' ]
bWendu 2
yWendu -5
tianqi 多云
fengxiang 北风
Name: 2018-01-03, dtype: object
dff. loc[ '2018-01-03' : '2018-01-05' , 'bWendu' : 'fengxiang' ]
bWendu yWendu tianqi fengxiang ymd 2018-01-03 2 -5 多云 北风 2018-01-04 0 -8 阴 东北风 2018-01-05 3 -6 多云~晴 西北风
4、使用条件表达式查询
bool列表的长度得等于行数或者列数
bool_map = ( dff[ "yWendu" ] < - 10 )
bool_map. head( )
ymd
2018-01-01 False
2018-01-02 False
2018-01-03 False
2018-01-04 False
2018-01-05 False
Name: yWendu, dtype: bool
dff. loc[ bool_map, : ]
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
bool_map1 = ( dff[ "bWendu" ] <= 30 ) & ( dff[ "yWendu" ] >= 15 ) & ( dff[ "tianqi" ] == '晴' ) & ( dff[ "aqiLevel" ] == 1 )
bool_map1. head( )
ymd
2018-01-01 False
2018-01-02 False
2018-01-03 False
2018-01-04 False
2018-01-05 False
dtype: bool
dff. loc[ bool_map1, : ]
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
5、调用函数查询
dff. loc[ lambda dff : ( dff[ "bWendu" ] <= 30 ) & ( dff[ "yWendu" ] >= 15 ) , : ]
def query_my_data ( dff) :
return dff. index. str . startswith( "2018-09" ) & df[ "aqiLevel" ] == 1
dff. loc[ query_my_data, : ]
pandas 新增数据列
直接赋值 df.apply df.assign 按条件选择分组分别赋值
0、读取csv数据
dfm = pd. read_csv( './datas/beijing_tianqi/beijing_tianqi_2018.csv' )
dfm. head( )
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、直接赋值的方法
清理温度列变成数字类型
dfm. loc[ : , "bWendu" ] = dfm[ "bWendu" ] . str . replace( "℃" , "" ) . astype( 'int32' )
dfm. loc[ : , "yWendu" ] = dfm[ "yWendu" ] . str . replace( "℃" , "" ) . astype( 'int32' )
dfm. head( )
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
dfm. loc[ : , 'wencha' ] = dfm[ 'bWendu' ] - dfm[ 'yWendu' ]
dfm. head( )
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 方法
def get_wendu_type ( x) :
if x[ "bWendu" ] > 33 :
return '高温'
if x[ "yWendu" ] < - 10 :
return '低温'
return '常温'
dfm. loc[ : , "wendu_type" ] = dfm. apply ( get_wendu_type, axis= 1 )
dfm[ "wendu_type" ] . value_counts( )
常温 328
高温 29
低温 8
Name: wendu_type, dtype: int64
3、df.assign 方法
dfm = dfm. assign(
f_yWendu = lambda x : x[ "yWendu" ] * 9 / 5 + 32 ,
f_bWendu = lambda x : x[ "bWendu" ] * 9 / 5 + 32
)
dfm. head( 5 )
ymd bWendu yWendu tianqi fengxiang fengli aqi aqiInfo aqiLevel wencha wendu_type f_yWendu f_bWendu 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
4、按条件选择分组分别赋值
按条件先选择数据,然后对这部分数据赋值新列 实例:高低温差大于10度,则认为温差大
dfm[ 'wencha_type' ] = ''
dfm. loc[ dfm[ 'bWendu' ] - dfm[ 'yWendu' ] > 10 , 'wencha_type' ] = '温差大'
dfm. loc[ dfm[ 'bWendu' ] - dfm[ 'yWendu' ] <= 10 , 'wencha_type' ] = '温差正常'
dfm[ 'wencha_type' ] . value_counts( )
温差正常 187
温差大 178
Name: wencha_type, dtype: int64
pandas 的数据统计方法
汇总类统计 唯一去重和按值计数 相关系数和协方差
dfm. head( 4 )
ymd bWendu yWendu tianqi fengxiang fengli aqi aqiInfo aqiLevel wencha wendu_type f_yWendu f_bWendu wencha_type 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 温差正常
1、汇总类统计
dfm. describe( )
bWendu yWendu aqi aqiLevel wencha f_yWendu f_bWendu count 365.000000 365.000000 365.000000 365.000000 365.000000 365.000000 365.000000 mean 18.665753 8.358904 82.183562 2.090411 10.306849 47.046027 65.598356 std 11.858046 11.755053 51.936159 1.029798 2.781233 21.159096 21.344482 min -5.000000 -12.000000 21.000000 1.000000 2.000000 10.400000 23.000000 25% 8.000000 -3.000000 46.000000 1.000000 8.000000 26.600000 46.400000 50% 21.000000 8.000000 69.000000 2.000000 10.000000 46.400000 69.800000 75% 29.000000 19.000000 104.000000 3.000000 12.000000 66.200000 84.200000 max 38.000000 27.000000 387.000000 6.000000 18.000000 80.600000 100.400000
dfm[ 'bWendu' ] . mean( )
18.665753424657535
dfm[ [ 'bWendu' , 'yWendu' ] ] . max ( )
bWendu 38
yWendu 27
dtype: int32
dfm[ 'wencha' ] . min ( )
2
2、唯一去重和按值计数
唯一去重,适合列出有哪些,不多的枚举
dfm[ "fengxiang" ] . unique( )
array(['东北风', '北风', '西北风', '西南风', '南风', '东南风', '东风', '西风'], dtype=object)
dfm[ "tianqi" ] . unique( )
array(['晴~多云', '阴~多云', '多云', '阴', '多云~晴', '多云~阴', '晴', '阴~小雪', '小雪~多云',
'小雨~阴', '小雨~雨夹雪', '多云~小雨', '小雨~多云', '大雨~小雨', '小雨', '阴~小雨',
'多云~雷阵雨', '雷阵雨~多云', '阴~雷阵雨', '雷阵雨', '雷阵雨~大雨', '中雨~雷阵雨', '小雨~大雨',
'暴雨~雷阵雨', '雷阵雨~中雨', '小雨~雷阵雨', '雷阵雨~阴', '中雨~小雨', '小雨~中雨', '雾~多云',
'霾'], dtype=object)
dfm[ "fengli" ] . unique( )
array(['1-2级', '4-5级', '3-4级', '2级', '1级', '3级'], dtype=object)
按值计数
dfm[ "fengxiang" ] . value_counts( )
南风 92
西南风 64
北风 54
西北风 51
东南风 46
东北风 38
东风 14
西风 6
Name: fengxiang, dtype: int64
dfm[ "tianqi" ] . value_counts( )
晴 101
多云 95
多云~晴 40
晴~多云 34
多云~雷阵雨 14
多云~阴 10
小雨~多云 8
雷阵雨 8
阴~多云 8
雷阵雨~多云 7
小雨 6
多云~小雨 5
雷阵雨~中雨 4
阴 4
中雨~雷阵雨 2
阴~小雨 2
中雨~小雨 2
霾 2
雷阵雨~阴 1
雷阵雨~大雨 1
小雨~雷阵雨 1
小雨~大雨 1
雾~多云 1
小雪~多云 1
阴~雷阵雨 1
小雨~中雨 1
小雨~阴 1
暴雨~雷阵雨 1
小雨~雨夹雪 1
阴~小雪 1
大雨~小雨 1
Name: tianqi, dtype: int64
dfm[ "fengli" ] . value_counts( )
1-2级 236
3-4级 68
1级 21
4-5级 20
2级 13
3级 7
Name: fengli, dtype: int64
3、相关系数和协方差
用途(超级厉害):
两只股票,是不是同涨同跌?程度多大?正相关还是负相关? 产品销量的波动,跟哪些因素正相关、负相关,程度有多大?
来自知乎,对于两个变量X、Y:
协方差:衡量同向反向程度 ,如果协方差为正,说明X,Y同向变化,协方差越大说明同向程度越高;如果协方差为负,说明X,Y反向运动,协方差越小说明反向程度越高。 相关系数:衡量相似度程度 ,当他们的相关系数为1时,说明两个变量变化时的正向相似度最大,当相关系数为-1时,说明两个变量变化的反向相似度最大
dfm. cov( )
bWendu yWendu aqi aqiLevel wencha f_yWendu f_bWendu bWendu 140.613247 135.529633 47.462622 0.879204 5.083614 243.953339 253.103845 yWendu 135.529633 138.181274 16.186685 0.264165 -2.651641 248.726292 243.953339 aqi 47.462622 16.186685 2697.364564 50.749842 31.275937 29.136033 85.432720 aqiLevel 0.879204 0.264165 50.749842 1.060485 0.615038 0.475498 1.582567 wencha 5.083614 -2.651641 31.275937 0.615038 7.735255 -4.772953 9.150506 f_yWendu 243.953339 248.726292 29.136033 0.475498 -4.772953 447.707326 439.116010 f_bWendu 253.103845 243.953339 85.432720 1.582567 9.150506 439.116010 455.586920
dfm[ "aqi" ] . corr( dfm[ "bWendu" ] )
0.07706705916811067
dfm[ "aqi" ] . corr( dfm[ "yWendu" ] )
0.026513282672968895
dfm[ "aqi" ] . corr( dfm[ "bWendu" ] - dfm[ "yWendu" ] )
0.2165225757638205
Pandas对缺失值的处理
Pandas使用这些函数处理缺失值:
isnull和notnull:检测是否是空值,可用于df和series dropna:丢弃、删除缺失值
axis : 删除行还是列,{0 or ‘index’, 1 or ‘columns’}, default 0 how : 如果等于any则任何值为空都删除,如果等于all则所有值都为空才删除 inplace : 如果为True则修改当前df,否则返回新的df fillna:填充空值
value:用于填充的值,可以是单个值,或者字典(key是列名,value是值) method : 等于ffill使用前一个不为空的值填充forword fill;等于bfill使用后一个不为空的值填充backword fill axis : 按行还是列填充,{0 or ‘index’, 1 or ‘columns’} inplace : 如果为True则修改当前df,否则返回新的df
读取excel的时候,忽略前几个空行 skiprows 参数控制
studf = pd. read_excel( './datas/student_excel/student_excel.xlsx' , skiprows= 2 )
studf. head( 10 )
Unnamed: 0 姓名 科目 分数 0 NaN 小明 语文 85.0 1 NaN NaN 数学 80.0 2 NaN NaN 英语 90.0 3 NaN NaN NaN NaN 4 NaN 小王 语文 85.0 5 NaN NaN 数学 NaN 6 NaN NaN 英语 90.0 7 NaN NaN NaN NaN 8 NaN 小刚 语文 85.0 9 NaN NaN 数学 80.0
检测空值
studf. isnull( ) . head( )
Unnamed: 0 姓名 科目 分数 0 True False False False 1 True True False False 2 True True False False 3 True True True True 4 True False False False
studf[ '分数' ] . isnull( ) . head( )
0 False
1 False
2 False
3 True
4 False
Name: 分数, dtype: bool
studf[ '分数' ] . notnull( ) . head( )
0 True
1 True
2 True
3 False
4 True
Name: 分数, dtype: bool
studf. loc[ studf[ '分数' ] . notnull( ) , : ] . head( 10 )
Unnamed: 0 姓名 科目 分数 0 NaN 小明 语文 85.000000 1 NaN NaN 数学 80.000000 2 NaN NaN 英语 90.000000 4 NaN 小王 语文 85.000000 6 NaN NaN 英语 90.000000 8 NaN 小刚 语文 85.000000 9 NaN NaN 数学 80.000000 10 NaN NaN 英语 90.000000 11 NaN 小啊 语文 86.507353 12 NaN NaN 数学 86.654412
删除全是空值的列
studf. dropna( axis= 1 , how= 'all' , inplace= True )
studf. head( 10 )
姓名 科目 分数 0 小明 语文 85.0 1 NaN 数学 80.0 2 NaN 英语 90.0 3 NaN NaN NaN 4 小王 语文 85.0 5 NaN 数学 NaN 6 NaN 英语 90.0 7 NaN NaN NaN 8 小刚 语文 85.0 9 NaN 数学 80.0
删除全是空值的行
studf. dropna( axis= 0 , how= 'all' , inplace= True )
studf. head( 10 )
姓名 科目 分数 0 小明 语文 85.000000 1 NaN 数学 80.000000 2 NaN 英语 90.000000 4 小王 语文 85.000000 5 NaN 数学 NaN 6 NaN 英语 90.000000 8 小刚 语文 85.000000 9 NaN 数学 80.000000 10 NaN 英语 90.000000 11 小啊 语文 86.507353
把分数为空的填充为0
studf[ '分数' ] . fillna( 0 , inplace= True )
studf. head( 10 )
姓名 科目 分数 0 小明 语文 85.000000 1 NaN 数学 80.000000 2 NaN 英语 90.000000 4 小王 语文 85.000000 5 NaN 数学 0.000000 6 NaN 英语 90.000000 8 小刚 语文 85.000000 9 NaN 数学 80.000000 10 NaN 英语 90.000000 11 小啊 语文 86.507353
将姓名的缺失值填充为上一个
studf. loc[ : , '姓名' ] = studf[ '姓名' ] . fillna( method= "ffill" )
studf. head( 10 )
姓名 科目 分数 0 小明 语文 85.000000 1 小明 数学 80.000000 2 小明 英语 90.000000 4 小王 语文 85.000000 5 小王 数学 0.000000 6 小王 英语 90.000000 8 小刚 语文 85.000000 9 小刚 数学 80.000000 10 小刚 英语 90.000000 11 小啊 语文 86.507353
将清洗好的数据写入excel文件
studf. to_excel( './datas/student_excel/student_excel_clean.xlsx' , index= False )
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
df4 = pd. read_csv( './datas/beijing_tianqi/beijing_tianqi_2018.csv' )
df4. loc[ : , 'bWendu' ] = df4[ 'bWendu' ] . str . replace( '℃' , '' ) . astype( 'int32' )
df4. loc[ : , 'yWendu' ] = df4[ 'yWendu' ] . str . replace( '℃' , '' ) . astype( 'int32' )
df4. head( )
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
Series 的排序
按照空气质量排序
df4[ 'aqi' ] . sort_values( ) . head( 10 )
271 21
281 21
249 22
272 22
301 22
246 24
35 24
33 24
10 24
273 25
Name: aqi, dtype: int64
df4[ 'aqi' ] . sort_values( ascending= False ) . head( 10 )
86 387
72 293
91 287
71 287
317 266
329 245
85 243
335 234
57 220
316 219
Name: aqi, dtype: int64
df4[ 'tianqi' ] . sort_values( ) . head( 10 )
225 中雨~小雨
230 中雨~小雨
197 中雨~雷阵雨
196 中雨~雷阵雨
112 多云
108 多云
232 多云
234 多云
241 多云
94 多云
Name: tianqi, dtype: object
DataFrame 的排序
单列排序
df4. sort_values( by= 'aqi' ) . head( 7 )
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 246 2018-09-04 31 18 晴 西南风 3-4级 24 优 1 35 2018-02-05 0 -10 晴 北风 3-4级 24 优 1
df4. sort_values( by= 'aqi' , ascending= False ) . head( 7 )
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 329 2018-11-26 10 0 多云 东南风 1级 245 重度污染 5 85 2018-03-27 27 11 晴 南风 1-2级 243 重度污染 5
多列排序 ------显然返回的是df
df4. sort_values( by= [ 'aqiLevel' , 'bWendu' ] ) . head( 7 )
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 24 2018-01-25 -3 -11 多云 东北风 1-2级 27 优 1 25 2018-01-26 -3 -10 晴~多云 南风 1-2级 39 优 1
df4. sort_values( by= [ 'aqiLevel' , 'bWendu' ] ) . head( 7 )
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 24 2018-01-25 -3 -11 多云 东北风 1-2级 27 优 1 25 2018-01-26 -3 -10 晴~多云 南风 1-2级 39 优 1
df4. sort_values( by= [ 'aqiLevel' , 'bWendu' ] , ascending= [ True , False ] ) . head( 7 )
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 226 2018-08-15 32 24 多云 东北风 3-4级 33 优 1 231 2018-08-20 32 23 多云~晴 北风 1-2级 41 优 1
Pandas字符串处理
使用.str
转换之后就可以使用python内置的各种字符串处理方法,当然这是pandas封装的,甚至还比标准库多
前面我们已经使用了字符串的处理函数: df[“bWendu”].str.replace(“℃”, “”).astype(‘int32’)
Pandas的字符串处理:
使用方法:先获取Series的str属性,然后在属性上调用函数; 只能在字符串列上使用,不能数字列上使用; Dataframe上没有str属性和处理方法 Series.str并不是Python原生字符串,而是自己的一套方法,不过大部分和原生str很相似;
Series.str字符串方法列表参考文档: https://pandas.pydata.org/pandas-docs/stable/reference/series.html#string-handling
本节演示内容:
获取Series的str属性,然后使用各种字符串处理函数 使用str的startswith、contains等bool类Series可以做条件查询 需要多次str处理的链式操作 使用正则表达式的处理
df5 = pd. read_csv( "./datas/beijing_tianqi/beijing_tianqi_2018.csv" )
df5. head( 7 )
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 5 2018-01-06 2℃ -5℃ 多云~阴 西南风 1-2级 32 优 1 6 2018-01-07 2℃ -4℃ 阴~多云 西南风 1-2级 59 良 2
df5. dtypes
ymd object
bWendu object
yWendu object
tianqi object
fengxiang object
fengli object
aqi int64
aqiInfo object
aqiLevel int64
dtype: object
1、获取Series的str属性,使用各种字符串处理函数
df5[ 'bWendu' ] . str . isnumeric( ) . value_counts( )
False 365
Name: bWendu, dtype: int64
df5[ 'bWendu' ] . str . isnumeric( ) . head( )
0 False
1 False
2 False
3 False
4 False
Name: bWendu, dtype: bool
2、使用str的startswith、contains等得到bool的Series可以做条件查询
condition = df5[ "ymd" ] . str . startswith( "2018-03" )
condition. head( )
0 False
1 False
2 False
3 False
4 False
Name: ymd, dtype: bool
df5. loc[ condition, : ] . head( 7 )
ymd bWendu yWendu tianqi fengxiang fengli aqi aqiInfo aqiLevel 59 2018-03-01 8℃ -3℃ 多云 西南风 1-2级 46 优 1 60 2018-03-02 9℃ -1℃ 晴~多云 北风 1-2级 95 良 2 61 2018-03-03 13℃ 3℃ 多云~阴 北风 1-2级 214 重度污染 5 62 2018-03-04 7℃ -2℃ 阴~多云 东南风 1-2级 144 轻度污染 3 63 2018-03-05 8℃ -3℃ 晴 南风 1-2级 94 良 2 64 2018-03-06 6℃ -3℃ 多云~阴 东南风 3-4级 67 良 2 65 2018-03-07 6℃ -2℃ 阴~多云 北风 1-2级 65 良 2
3、需要多次str处理的链式操作
怎样提取201803这样的数字月份? 1、replace 先将日期2018-03-31替换成20180331的形式 2、提取月份字符串201803
df5[ 'ymd' ] . str . replace( '-' , '' ) . head( 7 )
0 20180101
1 20180102
2 20180103
3 20180104
4 20180105
5 20180106
6 20180107
Name: ymd, dtype: object
df5[ 'ymd' ] . str . replace( '-' , '' ) . str . slice ( 0 , 6 ) . head( )
0 201801
1 201801
2 201801
3 201801
4 201801
Name: ymd, dtype: object
4、使用正则表达式的处理
首先不使用的情况是这样的
def get_nianyueri ( x) :
year, month, day = x[ "ymd" ] . split( "-" )
return f"{year}年{month}月{day}日"
df5[ "中文日期" ] = df5. apply ( get_nianyueri, axis= 1 )
df5[ "中文日期" ] . head( )
0 2018年01月01日
1 2018年01月02日
2 2018年01月03日
3 2018年01月04日
4 2018年01月05日
Name: 中文日期, dtype: object
df5[ '中文日期' ] . str . replace( '年' , '' ) . str . replace( '月' , '' ) . str . replace( '日' , '' ) . head( )
0 20180101
1 20180102
2 20180103
3 20180104
4 20180105
Name: 中文日期, dtype: object
然后是Series.str默认就开启了正则表达式模式的情况是这样的
df5[ '中文日期' ] . str . replace( '[年月日]' , '' ) . head( )
0 20180101
1 20180102
2 20180103
3 20180104
4 20180105
Name: 中文日期, dtype: object
理解axis参数
axis=0或’index’ 跨行梳出
axis=1或’columns’ 跨列梳出
后续篇目