《利用Python进行数据分析》—5
2019-07-17 本文已影响4人
皮皮大
#去除空白符、删除各种标点符号、正确的大写格式
states = [' Alabama ', 'Georgia!', 'Georgia!', '+georgia', 'FlOrIda', 'south carolina##', 'West virginia?']
通过re 模块和内建函数解决
import re
def clean_states(states):
result = []
for value in states:
value = value.strip() # 去掉左右空格
value = value.title() # 变成标题模式:首字母大写
value = re.sub('[+!#?]', '', value) # 将value中的几个特殊字符替换掉
result.append(value)
return result
clean_states(states)
# 定义一个去除特殊符号的函数,直接返回处理后的结果value
def remove_punctuation(value):
return re.sub("[+!#?]", "", value) # 匹配(此处是直接去掉)函数[]里面的一个或者多个符号
# 将需要在一组给定的字符串上执行的所有运算做成一个列表
clean_ops = [str.strip, remove_punctuation, str.title]
def clean_states(states, ops):
result = [] # 定义空列表用于存放数据
for value in states: # 判断value是否在原始数据中
for function in ops: # 判断函数是否在上面的三种处理方式的列表中
value = function(value) # 如果在里面,直接对value进行处理
result.append(value) # 所有的处理完之后再进行追加
return result # 最后进行返回result值
clean_states(states, clean_ops) # 传入参数,一个是原始数据,一个是三种处理方式的列表
结果:
['Alabama',
'Georgia',
'Georgia',
'Georgia',
'Florida',
'South Carolina',
'West Virginia']
lambda函数
- 单条语句,结果就是返回值
- 通过lambda进行定义
def apply_to_list(ints, func):
return [func(x) for x in ints]
ints = [1,2,4,5,3,8]
apply_to_list(ints, lambda x: x*2)
>>strings.sort(key=lambda x: len(set(list(x)))) # key就是用于传递的函数参数
>>strings
['aaaa', 'foo', 'abab', 'bar', 'card']
柯里化
lambda实现
通过部分参数应用,从现有函数衍生出新的函数的技术。
def add_number(x, y):
return x + y
# 从add_number派生新的函数,add_five函数
add_five = lambda y: add_number(5, y) # 此时第二个参数就是柯里化
functools模块实现
内置的functools模块的partial函数解决
from functools import partial
add_five = partial(add_number, 5)
生成器
能够以一种相同的方式对序列进行迭代是Python的重要特点。通过迭代器协议来实现。对字典的键进行迭代:
dict1 = {"a":1, "b":2, "c":3}
for key in dict1:
print(key)
dict1_iterator = iter(dict1)
dict1_iterator # 关于字典key进行迭代
list(dict1_iterator)
迭代器是种特殊对象。生成器是构造新的可迭代对的一种简单方式,几个特点:
- 一般的函数返回的是一个值
- 生成器则是以延迟的方式返回一个序列,即每次返回一个值挂起之后,直到下一个值被请求时再继续。
- 调用生成器不会马上执行,需要从生成器中请求元素
- 创建生成器只需要将函数中的
return
换成yield
def seq(n):
print("Generating squares from 1 to {0}".format(n))
for i in range(1, n+1):
yield i ** 2
result = seq(10) # 调用生成器
result # 不会立即执行代码,但是result中已经有了生成器对象的序列
image.png
从生成器中请求数据:
for x in gen:
print(x, end=" ")
Generating squares from 1 to 100
1 4 9 16 25 36 49 64 81 100
生成器表达式
将列表推导式两端的方括号改成圆括号即可:
for列表解析式
# 将100以内5的倍数求平方
>>result = (x**2 for x in range(100) if x % 5 == 0)
>>result
<generator object <genexpr> at 0x000001AF53940660>
list(result)
函数实现:
def five_power():
for x in range(100):
if x % 5 == 0:
yield x ** 2
result = five_power() # 调用函数
list(result)
image.png
sum(x for x in range(101)) # 生成器表达式取代列表解析式
# 生成器表达式
res = dict((i, i**2) for i in range(5))
res
# 通过for循环实现
dict1 = {}
for x in range(5):
if x not in dict1:
dict1[x] = x**2
print(dict1)
# 结果
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
itertools模块
itertools模块中有一组用于常见算法的生成器。常用的itertools
函数有:
例如:groupby
接受任何一个函数和序列
,根据返回值对序列中的元素进行分组:
import itertools
first_letter = lambda x: x[0]
names = ['Alan', 'Adam', 'Wes', 'Will', 'Albert', 'Steven']
for letter, names in itertools.groupby(names, first_letter): # 两个参数:序列和函数
print(letter, list(names)) # names是一个生成器
# 结果
A ['Alan', 'Adam']
W ['Wes', 'Will']
A ['Albert']
S ['Steven']
将上面的字符串分类问题用itertools
模块来解决:
import itertools
string_list = ['foo', 'card', 'bar', 'aaaa', 'abab','andeaf','abcdefgh','ababab']
string_length = lambda x: len(set(list(x)))
for length, string in itertools.groupby(strings, string_length):
print(length, list(string))
# 结果
1 ['aaaa']
2 ['foo', 'abab', 'ababab']
3 ['bar']
4 ['card']
5 ['andeaf']
8 ['abcdefgh']
image.png