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

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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
------------------------------

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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()

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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()

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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')

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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)

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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']]

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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']]

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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
# 取单个标量值-两种结果完全一样的方法loc位置, at位于
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
# 选取3到5行,1到3列的区域形成新DataFrame
df.iloc[3:5, 1:3]

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
B C
2013-01-04 14 15
2013-01-05 18 19
# 使用整数偏移定位列表,隔行选择, 可以多选,可以自定义重复
df.iloc[[1,2,2,4],[0,2]]

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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]]

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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'
# 使用 pd.read_csv 读取 csv 数据
ratings = pd.read_csv(fpath)
# 使用 df.head() 查看 dataframe 的前几行
ratings.head()

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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
# 使用 df.shape() 查看数据表的形状
ratings.shape # 看起来好像挺大的样子
(100836, 4)
# 列名列表
ratings.columns
Index(['userId', 'movieId', 'rating', 'timestamp'], dtype='object')
# 索引列表
ratings.index # 0-100836 步长1
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
names=['pdata', 'pv', 'uv'] # 自定义列名列表
)
df1

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
日期 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
# pandas 从数据库读取数据表需要有 mysql 连接
conn = pymysql.connect(
host='127.0.0.1',
user='root',
password='root',
database='stock',
charset='utf8'
)
# 从 数据库连接中通过执行原生sql读取数据表
df_sql = pd.read_sql('select * from k_goods', conn)
df_sql

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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 数据集结构

  1. Series
  2. DataFrame
  3. 从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
# 索引列表 dict.keys()
s1.index
RangeIndex(start=0, stop=4, step=1)
# 值列表 dict.values()
s1.values
array([1, 'a', 5.2, 7], dtype=object)

给定 values列表和index列表创建Series

### 给定 key 和 vlu
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') # 只要不是一个都仍是个Series
# 切片索引
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

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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
# 索引一列 返回一个Series
df3['year']
0    2000
1 2001
2 2002
3 2001
4 2002
Name: year, dtype: int64
# 索引多列 返回一个DataFrame
df3[['year', 'pop']]

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
year pop
0 2000 1.5
1 2001 1.7
2 2002 3.6
3 2001 2.4
4 2002 2.9
# 查询一列 返回Series
df3.loc[1]
state    Ohio
year 2001
pop 1.7
Name: 1, dtype: object
# 查询指定多列 返回DataFrame
df3.loc[[1:3]]
# 查询范围多列 返回DataFrame
df3.loc[[1, 3]]

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
state year pop
1 Ohio 2001 1.7
3 Nevada 2001 2.4

pandas 数据查询

Pandas查询数据的几种方法

  1. df.loc方法,根据行、列的标签值查询
  2. df.iloc方法,根据行、列的数字位置查询
  3. df.where方法
  4. df.query方法

.loc既能查询,又能覆盖写入,强烈推荐!

Pandas使用df.loc查询数据的方法

  1. 使用单个label值查询数据
  2. 使用值列表批量查询
  3. 使用数值区间进行范围查询
  4. 使用条件表达式查询
  5. 调用函数查询

注意

  • 以上查询方法,既适用于行,也适用于列
  • 注意观察降维dataFrame>Series>值

0、读取数据

数据为北京2018年全年天气预报

该数据的爬虫教程参见我的Python爬虫系列视频课程

dff = pd.read_csv('./datas/beijing_tianqi/beijing_tianqi_2018.csv')
dff.head()

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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()

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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()

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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
# 查询指定行的部分列 得到一个Series
dff.loc['2018-01-03', ['bWendu', 'yWendu']]
bWendu     2
yWendu -5
Name: 2018-01-03, dtype: object

2、使用值列表批量查询

# 查询部分指定行的指定列 得到Series
df.loc[['2018-01-03','2018-01-04','2018-01-05'], 'bWendu']
bWendu     2
yWendu -5
Name: 2018-01-03, dtype: object
# 查询区块 得到一个DataFrame
dff.loc[['2018-01-03','2018-01-04','2018-01-05'], ['bWendu', 'yWendu']]

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
bWendu yWendu
ymd
2018-01-03 2 -5
2018-01-04 0 -8
2018-01-05 3 -6

3、使用数值区间进行范围查询

注意:区间既包含开始,也包含结束

# 查询行区间的指定列 得到Series
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
# 查寻指定行的列区间 得到Series
dff.loc['2018-01-03', 'bWendu':'fengxiang']
bWendu        2
yWendu -5
tianqi 多云
fengxiang 北风
Name: 2018-01-03, dtype: object
# 行和列都按区间查询 得到DaTaFrame
dff.loc['2018-01-03':'2018-01-05', 'bWendu':'fengxiang']

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
bWendu yWendu tianqi fengxiang
ymd
2018-01-03 2 -5 多云 北风
2018-01-04 0 -8 东北风
2018-01-05 3 -6 多云~晴 西北风

4、使用条件表达式查询

bool列表的长度得等于行数或者列数

# 观察一下boolean条件 返回布尔对应关系表
bool_map = (dff["yWendu"]<-10)
bool_map.head() # 【单一条件查询,最低温度低于-10度的列表】
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
# 根据布尔关系对应表 查询10°C一下的天
dff.loc[bool_map, :]

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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
# 观察一下boolean条件 返回布尔对应关系表 【多个布尔对应关系表结合成目标布尔关系对应表】
# 【查询最高温度小于30度,并且最低温度大于15度,并且是晴天,并且天气为优的数据】
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
# 根据布尔关系对应表 查询10°C一下的天查询最高温度小于30度,并且最低温度大于15度,并且是晴天,并且天气为优的数据
dff.loc[bool_map1, :] # 看起来只有两天

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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、调用函数查询

# 直接写lambda表达式
dff.loc[lambda dff : (dff["bWendu"]<=30) & (dff["yWendu"]>=15), :]
# 编写自己的函数,查询9月份,空气质量好的数据
def query_my_data(dff):
return dff.index.str.startswith("2018-09") & df["aqiLevel"]==1 dff.loc[query_my_data, :]

pandas 新增数据列

  1. 直接赋值
  2. df.apply
  3. df.assign
  4. 按条件选择分组分别赋值

0、读取csv数据

dfm = pd.read_csv('./datas/beijing_tianqi/beijing_tianqi_2018.csv')
dfm.head()

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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()

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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()

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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 '常温' # 注意需要设置axis==1,这是series的index是columns
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( # assign 方法不会修改 dfm 而是会返回一个新的 DataFrame 对象
f_yWendu = lambda x : x["yWendu"] * 9 / 5 + 32,
# 摄氏度转华氏度
f_bWendu = lambda x : x["bWendu"] * 9 / 5 + 32
)
dfm.head(5)

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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 的数据统计方法

  1. 汇总类统计
  2. 唯一去重和按值计数
  3. 相关系数和协方差
# 先看一下前4行
dfm.head(4)

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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()

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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、相关系数和协方差

用途(超级厉害):

  1. 两只股票,是不是同涨同跌?程度多大?正相关还是负相关?
  2. 产品销量的波动,跟哪些因素正相关、负相关,程度有多大?

来自知乎,对于两个变量X、Y:

  1. 协方差:衡量同向反向程度,如果协方差为正,说明X,Y同向变化,协方差越大说明同向程度越高;如果协方差为负,说明X,Y反向运动,协方差越小说明反向程度越高。
  2. 相关系数:衡量相似度程度,当他们的相关系数为1时,说明两个变量变化时的正向相似度最大,当相关系数为-1时,说明两个变量变化的反向相似度最大
# 协方差矩阵:
dfm.cov()

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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)

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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()

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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
# 使用notnull查看非空的
studf['分数'].notnull().head()
0     True
1 True
2 True
3 False
4 True
Name: 分数, dtype: bool
# 筛选没有空分的行-这一步的目的是大致观察清晰的数据
studf.loc[studf['分数'].notnull(), :].head(10)

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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)

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
姓名 科目 分数
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)

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
姓名 科目 分数
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) # 无返回df,直接操作源内村
# studf.fillna({'分数': 0}, inplace=True) # 无返回df,直接操作原内存
# studf.loc[:, '分数'] = studf.fillna({'分数': 0}) # 有返回df
# studf.loc[:, '分数'] = studf['分数'].fillna(0) # 有返回df
# 以上为等效的方法
studf.head(10)

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
姓名 科目 分数
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

将姓名的缺失值填充为上一个

# 参数 ffill代表用上面的值填充,dfill代表用下面的值填充
studf.loc[:, '姓名'] = studf['姓名'].fillna(method="ffill") # 返回填充后的列,赋值给原来的列
# studf['姓名'] = studf['姓名'].fillna(method='ffill')
# studf['姓名'].fillna(method='ffill', inplace=True)
# 以上三种形式等效
studf.head(10)

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
姓名 科目 分数
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()

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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 的排序

按照空气质量排序

# 默认ascending为True代表升序
df4['aqi'].sort_values().head(10) # 也可以指定inplace=True代表在源内存上改
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) # sort_values 返回结果副本,也可指定inplace
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) # 按照空气质量升序

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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) # 按照空气质量降序

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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

# 优先按照空气质量等级,次按照最高温排序,默认ascending=True 即[两列都是升序]
df4.sort_values(by=['aqiLevel', 'bWendu']).head(7)

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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)

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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
# [分别指定升序和降序] ascending传入列表[True, None] None等效False
df4.sort_values(by=['aqiLevel', 'bWendu'], ascending=[True, False]).head(7)

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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的字符串处理:

  1. 使用方法:先获取Series的str属性,然后在属性上调用函数;
  2. 只能在字符串列上使用,不能数字列上使用;
  3. Dataframe上没有str属性和处理方法
  4. Series.str并不是Python原生字符串,而是自己的一套方法,不过大部分和原生str很相似;

Series.str字符串方法列表参考文档:

https://pandas.pydata.org/pandas-docs/stable/reference/series.html#string-handling

本节演示内容:

  1. 获取Series的str属性,然后使用各种字符串处理函数
  2. 使用str的startswith、contains等bool类Series可以做条件查询
  3. 需要多次str处理的链式操作
  4. 使用正则表达式的处理
df5 = pd.read_csv("./datas/beijing_tianqi/beijing_tianqi_2018.csv")
df5.head(7)

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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
# 不可以使用这样的 df5['aqi'].str.len()

2、使用str的startswith、contains等得到bool的Series可以做条件查询

# 条件是以'2018-03'开头 也就是查询了2018年3月的
condition = df5["ymd"].str.startswith("2018-03")
condition.head() # 前面都是False 到了2018-03就是True了 bool对应关系图
0    False
1 False
2 False
3 False
4 False
Name: ymd, dtype: bool
df5.loc[condition, :].head(7) # 查询三月的
# df5.loc[condition].head(7) # 等效方法
# df5[condition].head(7) # 等效方法

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
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
# 每次调用函数,都返回一个新Series,需要再次用 `.str`操作才能继续使用字符串操作方法
# df5["ymd"].str.replace("-", "").slice(0, 6) # 将会报错
df5['ymd'].str.replace('-', '').str.slice(0, 6).head()
# slice方法其实就是切片语法,直接[::]就可
# df5['ymd'].str.replace('-', '').str[0:6]
0    201801
1 201801
2 201801
3 201801
4 201801
Name: ymd, dtype: object

4、使用正则表达式的处理

首先不使用的情况是这样的

# 添加新列-如 2018年03月14日
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
# 链式操作,每次调用字符串处理方法都要先 `.str`
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' 跨列梳出

后续篇目





pandas 学习笔记【持续更新】的更多相关文章

  1. 数据分析之Pandas和Numpy学习笔记(持续更新)<1>

    pandas and numpy notebook        最近工作交接,整理电脑资料时看到了之前的基于Jupyter学习数据分析相关模块学习笔记.想着拿出来分享一下,可是Jupyter导出来h ...

  2. [读书]10g/11g编程艺术深入体现结构学习笔记(持续更新...)

    持续更新...) 第8章 1.在过程性循环中提交更新容易产生ora-01555:snapshot too old错误.P257 (这种情况我觉得应该是在高并发的情况下才会产生) 假设的一个场景是系统一 ...

  3. Semantic ui 学习笔记 持续更新

    这个semantic 更新版本好快~ 首先是代码的标识<code></code> 具体样式就是红框这样的 圈起来代码感觉不错 不过要在semantic.css里在加上如下样式~ ...

  4. Git学习笔记(持续更新)

    1.强制同步为远程的代码 远程仓库回退了commit的情况下(第2条描述之情况),强制同步远程的代码到本地 #更新远程最新的所有代码,但是不merge或者rebase git fetch --all ...

  5. R语言的学习笔记 (持续更新.....)

    1. DATE 处理 1.1 日期格式一个是as.Date(XXX) 和strptime(XXX),前者为Date格式,后者为POSIXlt格式 1.2 用法:as.Date(XXX,"%Y ...

  6. angularjs1学习笔记--持续更新

    angularJS使用的MVC为何不属于二十三种设计模式之一? MVC被GoF (Gang of Four,四人组, <Design Patterns: Elements of Reusable ...

  7. ggplot2 学习笔记 (持续更新.....)

    1. 目前有四种主题 theme_gray(), theme_bw() , theme_minimal(),theme_classic() 2. X轴设置刻度 scale_x_continuous(l ...

  8. # MongoDB学习笔记(持续更新)

    启动mongo服务 sodo mongo 显示数据库(显示数据库名称和大小,单位GB) > show dbs admin (empty) local 0.078GB test 0.078GB t ...

  9. GOF 的23种JAVA常用设计模式 学习笔记 持续更新中。。。。

    前言: 设计模式,前人总结下留给后人更好的设计程序,为我们的程序代码提供一种思想与认知,如何去更好的写出优雅的代码,23种设计模式,是时候需要掌握它了. 1.工厂模式 大白话:比如你需要一辆汽车,你无 ...

  10. BLE资料应用笔记 -- 持续更新

    BLE资料应用笔记 -- 持续更新 BLE 应用笔记 小书匠 简而言之,蓝牙无处不在,易于使用,低耗能和低使用成本.'让我们'更深入地探索这些方面吧. 蓝牙无处不在-,您可以在几乎每一台电话.笔记本电 ...

随机推荐

  1. vue 循环和v-if 不能混合使用

    <div class="item page-item" v-for="(item,i) in pageNum" @click="setCurre ...

  2. 实验3- 熟悉常用的 HBase 操作

        石家庄铁道大学信息科学与技术学院               实验报告 2018年----2019年  第一学期                       题目:  熟悉常用的 HBase ...

  3. java初学小项目-酒店客房管理系统

    最近初次接触JAVA,感觉之前学的C语言很有用,跟着视频做了一个小项目-酒店客房管理系统 /* 酒店客房管理系统 */ import java.util.Scanner;//通过键盘来输入命令需要的引 ...

  4. blkid命令 获取文件系统类型、UUID

    在Linux下可以使用blkid命令对查询设备上所采用文件系统类型进行查询.blkid主要用来对系统的块设备(包括交换分区)所使用的文件系统类型.LABEL.UUID等信息进行查询.要使用这个命令必须 ...

  5. 16 react 发送异步请求获取数据 和 使用Redux-thunk中间件进行 ajax 请求发送

    1.发送异步请求获取数据 1.引入 axios ( 使用 yarn add axios 进行安装 ) import axios from 'axios'; 2. 模拟 在元素完成挂载后加载数据 并初始 ...

  6. spark on yarn 安装笔记

    yarn版本:hadoop2.7.0 spark版本:spark1.4.0 0.前期环境准备: jdk 1.8.0_45 hadoop2.7.0 Apache Maven 3.3.3 1.编译spar ...

  7. LeJOS下eclipse通过USB连接EV3

    适用情况:在eclipse安装好LeJOS插件后,再通过USB连接EV3. 第一:更新驱动 在<设备管理器-网络适配器>下更新RNDIS/Ethernet Gadget,电脑需要先连接EV ...

  8. SQL Server 2017 安装问题

    遇到问题 Polybase 要求安装 Oracle JRE7 更新 规则失败 安装完毕之后,登录提示:您试图连接的 SQL Server 实例未安装 安装完SQL Server 2017 后,无法启动 ...

  9. OpenSSL加密证书

    用于建立安全站点的工具,颁发证书,例如https,ftps等 默认配置文件: [root@bogon CA]# cat /etc/pki/tls/openssl.cnf [ CA_default ] ...

  10. c++ 排序 冒泡 插入 选择 快速

    //冒泡 #include <iostream> using namespace std; void bubbleSort(int* list,int index) { ;i--) //i ...