python数据分分析

一只叫SheZQ / 2023-08-09 / 原文

数据处理的步骤

graph LR 处理数据-->清洗数据

目的:如何用python操作数据
对象:需要的是结构化的数据
工具:用到的库

库名 用途
Numpy
Pandas
matplotlib
JupyterNotebook
Scipy
Scikit-learn
Statsmodels

python的内建数据结构;元组、列表、字典

元组

>tuple = (4,5,6)

元组的拆包特性:

>tuple = (4,5,6)
>a,b,c = tup
>b
5

嵌套元组的拆包特性

>tuple = 4,5,(6,7)
>a,b,(c,d) = tuple
>d
7

利用元组的拆包特性,实现交换

>a,b =1,2
>b,a = a,b
>a
2
>b
1

python自带的更高级的拆包特性:*rest(余下的部分),帮助你从某个起始部分采集数据

>values = 1,2,3,4,5,6
>a,b,*rest = values
>rest
[4,5,6]

一般为了方便,开发者会用 *_代替*rest来表示非采集部分的变量

元组的统计计数:count,统计某个元素出现的次数

>a = (1,2,2,2,3,4,4,2)
>a.count(2)
4

元组和列表的区别:可变与不可变。

列表

增加与移除元素的方法

  1. 增加到尾巴:append
  2. 插入到任意位置:insert
  3. 移除元素:pop、
  4. 移除第一个符合的元素:remove

不考虑性能,可以使用append和remove,将python列表作为一个完全合适的数据结构

查找元素

  1. 查找元素是否在列表中:in
  2. 查找元素是否不在列别中: not in

列表的查找性能很差

列表与“字典和集合”相比,检查列表中是否有一个值,是非常缓慢的,这是因为python在列表中是线性逐个扫描的机制,而在集合和字典中是全局同时。

python数据结构 检查方式
列表 逐个扫描
字典、集合 全局扫描

性能更好的添加列表的方式

用“+”号可以添加列表内容,但因为这样链接过程创建了新的列表,是一种相对高代价的操作(内存占用),所以使用extend将元素加到已存在的列表是更好的方式。

排序:sort

  1. 正常引用sort用大小排序
  2. 给排序附加条件:(key=)
b.sort(ley = len) #按字符长度排序

使用二分搜索并将值插到合适的位置
bisect.bisect:找到元素应被插入的位置,保持排序
bisect.insort:将元素插入到对应位置

import bisect
> c = [1,2,2,2,3,4,7]
> bisect.bisect(c,2) # 排序2,显示应该排队位置在4。位置从0开始,此时并未插入元素
> 4
> bisect.bisect(c,5) # 5对应排序,显示应该排队位置在6,位置从0开始,此时并未插入元素
> 6
> bisect.insort(c,6) # 插入6,此时插入元素
> c
> [1,2,2,2,3,4,6,7]

需要注意:
bisect并不会检测列表是否自己排序,如果对未排序的列表使用bisect,他能用但结果不一定正确。

切片

切片基本上使用[start:stop]这种形式.。
负索引可以反着搜索。
步进值:[::2]

如果需要对元组或者列表进行翻转,可以将步进值传入-1:[::-1]

构建索引:enumerate(翻译成中文:列举、枚举)

for i,v in enumerate(list): # i是索引,v是值

比如我们要构建索引:

> some_list = ["foo","bar","baz"]
> mapping = {}
> for i,v in enumerate(some_list):
>	mapping[v] = i
> mapping
{"foo":1,"bar:2","baz":3}

按照顺序排列,然后出一个新序列:sorted

> sorted([7,1,2,2,6,0,3,2])
[0, 1, 2, 2, 3, 6, 7]
> sorted("horse race")
[' ', 'a', 'c', 'e', 'e', 'h', 'o', 'r', 'r', 's']

配对zip

> seq1 = ["foo","bar","baz"]
> seq2 = ["one","two","three"]
> zipped = (seq1,seq2)
> list(zipped)
[['foo', 'bar', 'baz'], ['one', 'two', 'three']]

zip处理的长度由最短的序列决定

> seq3 =[False,True]
> list(zip(seq1,seq2,seq3))

[('foo', 'one', False), ('bar', 'two', True)]

zip的使用场景:同时遍历多个序列

> for i,(a,b) in enumerate(zip(seq1,seq2)):
>    print("{0}:,{1},{2}".format(i,a,b))

0:,foo,one
1:,bar,two
2:,baz,three

zip的使用场景:行列置换

> people = [("ZQ","She"),("Kate","Liu"),("Sopu","Wu")]
> first_names,last_names = zip(*people)
> first_names

('ZQ', 'Kate', 'Sopu')

> last_names

('She', 'Liu', 'Wu')

倒序排序:reversed

reversed是一个生成器(生成器:没有实例的时候,是不会产生一个倒序的列表)

> list(reversed(range(10)))

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

字典dict

{key:value} 键值对,添加

empty_dict = {}
d1 = {"a":"some value","b":[1,2,3.4]}
print(d1)
d1[7] = "an integer" #添加键值对
print(d1)

> {'a': 'some value', 'b': [1, 2, 3.4]}
> {'a': 'some value', 'b': [1, 2, 3.4], 7: 'an integer'}

只能搜索键,不能搜索值:in

"b" in d1

> True

删除的两种方式:del,pop

graph LR A("dict的删除")---B("del:直接删除") A---C("pop:pop方法删除的同时返回被删的值,并删除键")
d1[5] = "some value"
d1["dummy"]="another value"
print(d1)

> {'a': 'some value', 'b': [1, 2, 3.4], 7: 'an integer', 5: 'some value', 'dummy': 'another value'}

del d1[5] # 直接删除模式
d1
> {'a': 'some value','b': [1, 2, 3.4],7: 'an integer','dummy': 'another value'}

remo = d1.pop("dummy") #先存储返回值
d1 #然后才能删除
> {'a': 'some value', 'b': [1, 2, 3.4], 7: 'an integer'}

迭代器:返回的keys值,values值

list(d1.keys())
> ['a', 'b', 7]

list(d1.values())
> ['some value', [1, 2, 3.4], 'an integer']

d1.update({"b":"foo","c":12}) # update可以用来合并两个字典
d1
> {'a': 'some value', 'b': 'foo', 7: 'an integer', 'c': 12}
  • 排序会乱:update方法改变了字典中元素位置,
  • 会覆盖相同的:因此对于任何原字典中已经存在的键,如果传给update方法的数据也含有相同的键,则它的值将会被覆盖。

两个序列按元素配对

mapping ={}
for key,value in zip(key_list,value_list):
	mapping[key]=value  #构建字典

字典的本质是:含有两个元素的元组,基于这个原理,我们可以用“元组”的数据结构来构建“字典”

\[含有2个元素的元组=字典 \]

mapping={}
dict(zip(range(5),reversed(5))) #用两个元组构建字典
mapping
> {0:4,1:3,2:2,3:1,4:0} # 构建字典成功

还有一种字典推导式

设置默认值
第一种解题方法:通常情况下的代码逻辑:

if key in some_dict:
	value = some_dict[key]
else:
	value = default_value

第二种解题方法:get方法 和 pop方法

value = some_dict.get(key,default_value)

会在不是字典的时候发生的情况:

  1. get方法,返回none
  2. pop方法,抛出异常

你能想象一个场景,用一些字词组组成数据结构“列表”

words = ["apple","bat","bar","atom","book"]

接下来实现一个要求:1.分类

by_letter = {}
for word in words:
	letter = word[0]
	if letter not in by_letter:
	by_letter[letter] = [word] # 以首字母形成字典
	else:
	by_letter[letter].append(word) # 在字典内部添加

by_letter
> {"a":["apple","atom"],"b":["bat","bar","book"]}

实现分类更简单的方法

字典的setdefault方法,实现分类

for word in words:
	letter = word[0]
	by_letter.setdefault(letter,[]).append(word)

内建得集合模块类:defaultdict,实现分类功能

from collections import defaultdict
by_letter = defaultdict(list)    # 传入类型
for word in words:
	by_letter[word[0]].append(word)

字典中得“键"是不可变得对象:所以我引用了哈希值得概念,我们可以使用哈希函数让值变得唯一。

hash('string') # 字符串是唯一得
>  
hash((1,2,(2,3))) # 元组是唯一得
> 
hash((1,2,[2,3])) # 列表是可变得,所以会哈希失败
>

为了将列表作为键、一种方式就是将其转换成元组。元组内部可以哈希化,它就可以哈希化。

集合:set

集合得特性:无序、唯一

创建方式:set函数、或者大括号{}。

编制模块