Linking

Capturing Life & Tech

  • 主页
  • 随笔
  • 关于我
所有文章 外链

Linking

Capturing Life & Tech

  • 主页
  • 随笔
  • 关于我

《利用Python进行数据分析》读书笔记-7-第七章-数据规整化:清理、转换、合并与重塑

阅读数:次 2017-04-14
字数统计: 2.4k字   |   阅读时长≈ 12分

合并数据集

pandas对象中的数据可通过内置方式合并:

  • pandas.merge根据键将不同DataFrame种的行连接起来,实现的是数据库的连接操作;
  • panda.concat沿一条轴将多个对象堆叠在一起;
  • 实例方法combine_first将重复数据编结在一起,用一个对象中的值填写另一个中的缺失值。

数据库风格的DataFrame合并

数据集的合并(merge)和连接(join)是通过键将行连接起来的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
df1 = DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
'data1': range(7)})
df2 = DataFrame({'key': ['、a', 'b', 'c'],
'data2': range(3)})
# print df1
# data1 key
# 0 0 b
# 1 1 b
# 2 2 a
# 3 3 c
# 4 4 a
# 5 5 a
# 6 6 b

# print df2
# data2 key
# 0 0 a
# 1 1 b
# 2 2 c

# print pd.merge(df1, df2)
# data1 key data2
# 0 0 b 1
# 1 1 b 1
# 2 6 b 1
# 3 2 a 0
# 4 4 a 0
# 5 5 a 0
# 6 3 c 2

# 这里默认将重叠列列名当做键;显式指定哪列连接用on参数
pd.merge(df1, df2, on='key')
# 还可以分别指定左右连接的键值,left_on,right_on
# 默认merge"inner"连接,结果中的键是交集
# how参数,'inner'是交集,outer是并集

# 重复列名的处理
# merge的suffixes参数,指定附加到左右两个DataFrame对象的重叠列名上的字符串

两边都有的列就都有数据,一边有列一边的数据,没有就用缺省值NaN填充。

索引上的合并

DataFrame的连接键位于索引上;传入left_index=True或right_index=True(或两者)指定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
left1 = DataFrame({'key': ['a', 'b', 'c', 'a', 'b', 'a'],
'value': range(6)})
right1 = DataFrame({'group_value': [3.5, 7]}, index=['a', 'b'])
# print pd.merge(left1, right1, left_on='key', right_index=True)
# key value group_value
# 0 a 0 3.5
# 3 a 3 3.5
# 5 a 5 3.5
# 1 b 1 7.0
# 4 b 4 7.0

# 若要取并集,用how='outer';一边没有的会用缺省值NaN填充
# print pd.merge(left1, right1, left_on='key', right_index=True, how='outer')
# key value group_value
# 0 a 0 3.5
# 3 a 3 3.5
# 5 a 5 3.5
# 1 b 1 7.0
# 4 b 4 7.0
# 2 c 2 NaN

# 层次化索引,暂时不看了,用到再研究;
# 层次化索引,只是指明合并键是多个列的列表形式,left_on=['a','b']

# DataFrame的join方法,可以实现同样的功能,而不管是否有重叠列
# left.join([right, another])

对于像这样的东西,了解一下,知道有这么个东西,以后用到能想到,查一下;
现在第一次看没必要看得这么深,也很难懂,看不懂还影响了心情。

轴向连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
arr = np.arange(12).reshape((3, 4))
# print arr
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]

# print np.concatenate([arr,arr],axis=1)
# [[ 0 1 2 3 0 1 2 3]
# [ 4 5 6 7 4 5 6 7]
# [ 8 9 10 11 8 9 10 11]]

s1 = Series([0, 1], index=['a', 'b'])
s2 = Series([2, 3, 4], index=['c', 'd', 'e'])
s3 = Series([5, 6], index=['f', 'g'])
# print pd.concat([s1,s2,s3])
# a 0
# b 1
# c 2
# d 3
# e 4
# f 5
# g 6
# dtype: int64

# 默认concat在axis=0上工作,产生一个新的Series,如axis=1(axis=1是列)则会产生一个DataFrame
# print pd.concat([s1, s2, s3], axis=1)
# 0 1 2
# a 0.0 NaN NaN
# b 1.0 NaN NaN
# c NaN 2.0 NaN
# d NaN 3.0 NaN
# e NaN 4.0 NaN
# f NaN NaN 5.0
# g NaN NaN 6.0

合并重叠数据

NumPy的where函数,实现合并两个有重叠部分数据集;Series的combine_first方法实现同样的功能,且数据对齐。

重塑和轴向旋转

重新排列表格型数据的基础运算,谓之重塑(reshape)或轴向旋转运算(pivot)。

重塑层次化索引

  • stack:将列转为行;
  • unstack:将行转为列。

数据转换

移除重复数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
data = DataFrame({'k1':['one']*3 + ['two']*4,
'k2':[1,1,2,3,4,4,5]})
# print data
# k1 k2
# 0 one 1
# 1 one 1
# 2 one 2
# 3 two 3
# 4 two 4
# 5 two 4
# 6 two 5

## 判断重复
# print data.duplicated()
# 0 False
# 1 True
# 2 False
# 3 False
# 4 False
# 5 True
# 6 False
# dtype: bool

## 移除重复
# print data.drop_duplicates()
# k1 k2
# 0 one 1
# 2 one 2
# 3 two 3
# 4 two 4
# 6 two 5

## 指定判断重复项的列;如还有一列值,只通过k1过滤重复项
data['v1'] = range(7)
# print data.drop_duplicates(['k1'])
# k1 k2 v1
# 0 one 1 0
# 3 two 3 3

了解到有这么个知识点可以完成那些功能,将来遇到要实现的时候能回忆起来就可以了。

利用函数或映射进行数据转换

Series的map方法可接受一个函数或含有映射关系的自典型对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
## 肉类
data = DataFrame({'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami', 'coned', 'Bacon', 'Pastrami', 'honey', 'nova'],
'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
# print data
# food ounces
# 0 bacon 4.0
# 1 pulled pork 3.0
# 2 bacon 12.0
# 3 Pastrami 6.0
# 4 coned 7.5
# 5 Bacon 8.0
# 6 pastrami 3.0
# 7 honey 5.0
# 8 nova 6.0

## 添加该肉类食物的动物本体
meat_to_animal = {
'bacon': 'pig',
'pulled pork': 'pig',
'Pastrami': 'cow',
'coned': 'cow',
'honey': 'pig',
'nova': 'salmon'
}
data['animal'] = data['food'].map(str.lower).map(meat_to_animal)
## 转换了大小写
# print data
# food ounces animal
# 0 bacon 4.0 pig
# 1 pulled pork 3.0 pig
# 2 bacon 12.0 pig
# 3 Pastrami 6.0 NaN
# 4 coned 7.5 cow
# 5 Bacon 8.0 pig
# 6 Pastrami 3.0 NaN
# 7 honey 5.0 pig
# 8 nova 6.0 salmon

## map是一种实现元素级转换以及其他数据清理工作的便捷方式。

替换值

replace提供了简单灵活的替换方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
data = Series([1.,-999.,2.,-999.,-1000.,3.])
# print data
# 0 1.0
# 1 -999.0
# 2 2.0
# 3 -999.0
# 4 -1000.0
# 5 3.0
# dtype: float64

## -999可能是缺失数据标记值,替换成pandas的NA
# print data.replace(-999, np.nan)
# 0 1.0
# 1 NaN
# 2 2.0
# 3 NaN
# 4 -1000.0
# 5 3.0
# dtype: float64

## 一次替换多个值为一个值
# print data.replace([-999,-1000], np.nan)
# 0 1.0
# 1 NaN
# 2 2.0
# 3 NaN
# 4 NaN
# 5 3.0
# dtype: float64

## 分别替换为不同值
# print data.replace([-999,-1000], [np.nan,0])
# 0 1.0
# 1 NaN
# 2 2.0
# 3 NaN
# 4 0.0
# 5 3.0
# dtype: float64

字符串操作

字符串对象方法

1.连接符
join连接列表或元祖

1
2
3
4
# print piece 
# ['a','b','c']
# print '::'.join(pieces)
# 'a::b::c'

2.子串定位in关键字

1
2
3
4
5
# print 'guido' in val
# True
## 可以用index和find查找子串
val.index(',')
val.find(':')

3.count计算子串出现的次数

1
val.conut(',')

正则表达式

re模块函数可分三大类:模式匹配
替换以及拆分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import re

# 空白符(制表符、空格、换行符等)
# text = "foo bar\t baz \tqux"
# print re.split('\s+', text)
# ['foo', 'bar', 'baz', 'qux']

# re.compile编译regex以得到一个可重用的regex对象
regex = re.compile('\s+')
# print regex.split(text)
# ['foo', 'bar', 'baz', 'qux']
# print regex.findall(text)
# [' ', '\t ', ' \t']
# 建议使用re.compile创建regex对象,节省CPU

# re.IGNORECASE对大小写不敏感

text1 = """Dave lin@qq.com
lin king@163.com
king wu@sina.com
ryle ryal@gmail.com
"""

pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'
regex = re.compile(pattern, flags=re.IGNORECASE)
# print regex.findall(text1)
# []

m = regex.search(text1)
# print m
# none

# regex.sub方法匹配成指定字符串
# print regex.sub('REDACTED', text1)

# 将邮件地址分成用户名、域名及域后缀三部分,用()包起来即可
pattern1 = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})'
regex1 = re.compile(pattern1, flags=re.IGNORECASE)

pandas中矢量化的字符串函数

清理散乱数据,字符串规整化工作。
data.map,所有字符串和正则表达式方法都能被应用于(传入lambda表达式或其他函数)各个值,但如果存在NA就会报错。通过Series的str属性即可访问这些方法。如str.contains检查是否含”gmail”.

1
data.str.contains('gmail')

示例:USDA食品数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import json

db = json.load(open('../pydata-book-master/ch07/foods-2011-10-03.json'))

# print len(db)
# 6636

# print db[0].keys()
# [u'portions', u'description', u'tags', u'nutrients', u'group', u'id', u'manufacturer']

# print db[0]['nutrients'][0]
# {u'units': u'g', u'group': u'Composition', u'description': u'Protein', u'value': 25.18}

# nutrients = DataFrame(db[0]['nutrients'])
# print nutrients[:7]
# description group units value
# 0 Protein Composition g 25.18
# 1 Total lipid (fat) Composition g 29.20
# 2 Carbohydrate, by difference Composition g 3.06
# 3 Ash Other g 3.28
# 4 Energy Energy kcal 376.00
# 5 Water Composition g 39.28
# 6 Energy Energy kJ 1573.00

# DataFrame可以只抽取一部分字段,如食物的名称、分类、编号以及制造商
info_key = ['description', 'group', 'id', 'manufacturer']
info = DataFrame(db, columns=info_key)
# print info[:5]
# description group id manufacturer
# 0 Cheese, caraway Dairy and Egg Products 1008
# 1 Cheese, cheddar Dairy and Egg Products 1009
# 2 Cheese, edam Dairy and Egg Products 1018
# 3 Cheese, feta Dairy and Egg Products 1019
# 4 Cheese, mozzarella, part skim milk Dairy and Egg Products 1028

# 查看食物类别分布情况
# print pd.value_counts(info.group)[:10]
# Vegetables and Vegetable Products 812
# Beef Products 618
# Baked Products 496
# Breakfast Cereals 403
# Legumes and Legume Products 365
# Fast Foods 365
# Lamb, Veal, and Game Products 345
# Sweets 341
# Fruits and Fruit Juices 328
# Pork Products 328
# Name: group, dtype: int64

nutrients = []
for rec in db:
fnuts = DataFrame(rec['nutrients'])
fnuts['id'] = rec['id']
nutrients.append(fnuts)

nutrients = pd.concat(nutrients, ignore_index=True)
# print nutrients
# 丢弃重复项
# print nutrients.duplicated().sum()
# 14179
# nutrients = nutrients.drop_duplicates()
# print nutrients

# 明确重命名
col_mapping = {'description': 'food',
'group': 'fgroup'}

# info = info.rename(columns=col_mapping, copy=False)
# print info
  • 本文作者: Linking
  • 本文链接: https://linking.fun/2017/04/14/《利用Python进行数据分析》读书笔记-7-第七章-数据规整化:清理、转换、合并与重塑/
  • 版权声明: 版权所有,转载请注明出处!
  • Python
  • cs

扫一扫,分享到微信

《利用Python进行数据分析》读书笔记-8-第八章-绘图和可视化
ListView嵌套GridView显示多张图片出现图片重复、错乱、闪烁等问题
  1. 1. 合并数据集
    1. 1.1. 数据库风格的DataFrame合并
    2. 1.2. 索引上的合并
    3. 1.3. 轴向连接
    4. 1.4. 合并重叠数据
  2. 2. 重塑和轴向旋转
    1. 2.1. 重塑层次化索引
  3. 3. 数据转换
    1. 3.1. 移除重复数据
    2. 3.2. 利用函数或映射进行数据转换
    3. 3.3. 替换值
  4. 4. 字符串操作
    1. 4.1. 字符串对象方法
    2. 4.2. 正则表达式
    3. 4.3. pandas中矢量化的字符串函数
  5. 5. 示例:USDA食品数据库
© 2015-2026 Linking
GitHub:hexo-theme-yilia-plus by Litten
本站总访问量次 | 本站访客数人
  • 所有文章
  • 外链

tag:

  • weather
  • 需求
  • essay
  • basketball
  • olympic
  • nginx
  • APPScan
  • SQl盲注
  • xss
  • Ajax
  • ajax
  • ai
  • agent
  • openclaw
  • ccf
  • Nginx
  • HTML5
  • html5
  • hmtl5
  • sse
  • JavaScriptCore
  • Oracle
  • operation
  • Linux
  • deploy
  • Mac Office
  • markdown
  • ListView
  • GridView
  • MySQL
  • 慢查询
  • mongodb
  • 转置
  • thought
  • network
  • ubuntu
  • NetworkManager
  • RFKill
  • Netplan
  • avatar
  • cocoa
  • blog
  • Gitalk
  • container
  • macvlan
  • docker
  • oracle
  • cookie
  • patch
  • gitea
  • git
  • iOS
  • https
  • 多线程
  • bundle
  • 兼容性
  • HTTP
  • 绘图
  • cs
  • java
  • 效率
  • 快捷键
  • route
  • nodejs
  • pip
  • arcgis
  • arcgis 建模
  • 标识
  • redis
  • read
  • bookList
  • running
  • showdoc
  • disk
  • unit-test
  • D.Wade
  • thoughts
  • duoduo
  • Python
  • python
  • tomcat
  • 读书节
  • session
  • jdk
  • war
  • 加班
  • Android onclick事件监听
  • 正则
  • 手机品牌匹配
  • ntp
  • OpenLayers
  • Geoserver
  • wechat
  • 微信公众号
  • 爬虫
  • WeChat
  • 张靓颖
  • 动漫
  • vpn
  • PPT
  • MarkDown
  • plan
  • 朱赟
  • 极客时间专栏
  • 极客邦
  • 模块化
  • MVC
  • excel
  • NBA
  • kobe
  • team
  • crawler
  • 进度条
  • ssl
  • book
  • anti-stealing-link
  • Agentic Engineering
  • Vibe Coding
  • Software 3.0
  • Andrej Karpathy
  • LLM
  • Programming
  • complain

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia-plus根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • GitHub Trending
  • OpenAI ChatGPT
  • Gitee码云
  • 简书
  • CSDN