利用python进行数据分析~第三章

3.1 数据结构和序列

元组是一个固定长度,不可改变的python序列对象。创建元组的方法就是用逗号分隔一列值

tup = 4,5,6
print(tup)
(4, 5, 6)

当用复杂的表达式定义元组时,将值放到圆括号中

nested_tup = (4,5,6),(7,8)
print(nested_tup)
((4, 5, 6), (7, 8))

tuple可以将任意序列或迭代器转换成元组,同样可以用方括号访问元组中的元素

tuple([4,0,2])
(4, 0, 2)
tuple('string')
('s', 't', 'r', 'i', 'n', 'g')
tup[0]
's'

如果元组中的某个对象是可变的,比如列表,可以在原位进行修改。可以用加号运算符将元组串联起来,元组乘以一个整数,像列表一样,会将几个元组的复制串联起来。对象之间是引用的关系而不是复制

(4, None, 'foo') + (6, 0) + ('bar',)
(4, None, 'foo', 6, 0, 'bar')
('foo', 'bar') * 4
('foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'bar')

拆分元组

seq = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
for a, b, c in seq:
    print('a={0}, b={1}, c={2}'.format(a, b, c))
a=1, b=2, c=3
a=4, b=5, c=6
a=7, b=8, c=9

tuple方法
count()可以统计某个值的出现频率

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

列表长度可变,内容可以被修改。可以用方括号定义或用list函数

tup = ('foo', 'bar', 'baz')
list(tup)
['foo', 'bar', 'baz']

list 函数常用来在数据处理中实体化迭代器或生成器:

list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

添加和删除元素
可以用append在列表末尾添加元素
insert可以在特定位置插入元素,insert的逆运算是pop,它移除并返回指定位置的元素。remove去除某个值,其会先寻找第一个值并除去
用in可以检查列表是否包含某个值,否定in可以再加上一个not

print(b_list)
      ['foo', 'bar', 'baz']
b_list.insert(1,'red')
     ['foo', 'red', 'bar', 'baz']
b_list.pop(2)
    ['foo', 'red', 'baz']
'dwarf' in b_list
   False
'dwarf' not in b_list
   True

串联和组合列表
与元组类似,可以用加号将两个列表串联起来
如果已经定义一个列表,用extend方法可以追加多个元素

[4, None, 'foo'] + [7, 8, (2, 3)]
      [4, None, 'foo', 7, 8, (2, 3)]
x = [4, None, 'foo']
x.extend([7, 8, (2, 3)])
print(x)
[4, None, 'foo', 7, 8, (2, 3)]

sort函数可以将一个列表原地排序
切片
切片的基本形式是在方括号中使用start:stop,负数表明从后往前切片。在第二个冒号后面使用step,可以隔一个取一个元素。使用-1可以将列表或元组颠倒过来

seq = [7, 2, 3, 7, 5, 6, 0, 1]
seq[1:5]
      [2, 3, 7, 5]
seq[-4:]
      [5, 6, 0, 1]
seq[::2]
     [7, 3, 5, 0]
seq[::-1]
      [1, 0, 6, 5, 7, 3, 2, 7]

序列函数
enumerate函数:在索引数据时,使用enumerate计算序列dict映射到位置的值

some_list = ['foo', 'bar', 'baz']
mapping = {}
for i, v in enumerate(some_list):
    mapping[v] = i
print(mapping)
      {'foo': 0, 'bar': 1, 'baz': 2}

sorted函数可以从任意序列的元素返回一个新的排好序的列表

sorted([7, 1, 2, 6, 0, 3, 2])
           [0, 1, 2, 2, 3, 6, 7]

zip函数可以将多个列表,元组或其它序列成对组合成一个元组列表

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

zip可以处理任意多的序列,元素个数取决于最短的序列;同时迭代多个序列可结合enumerate使用

seq3 = [False, True]
list(zip(seq1, seq2, seq3))
     [('foo', 'one', False), ('bar', 'two', True)]

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

reversed函数可以从后向前迭代一个序列,其是一个生成器,只有实例化之后才能创建翻转的序列

list(reversed(range(10)))
     [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

字典是键值对的大小可变的集合,键和值都是python对象。创建字典的方法之一是使用尖括号,用冒号分隔键和值

empty_dict = {}
d1 = {'a' : 'some value', 'b' : [1, 2, 3, 4]}
print(d1)
       {'a': 'some value', 'b': [1, 2, 3, 4]}

可以像访问列表或元组中的元素一样,访问,插入或设定字典中的元素

d1[7] = 'an integer'
print(d1)
       {'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer'}

可以用检查列表和元组是否包含某个值的方法,检查字典中是否包含某个键

'b' in d1
    True

可以用 del 关键字或 pop 方法(返回值的同时删除键)删除值,用 update 方法可以将一个字典与另一个融合,updata方法是原地改变字典,因此任何传递给updata的键的旧的值都会被舍弃

d1.update({'b' : 'foo', 'c' : 12})
print(d1)
{'a': 'some value', 'b': 'foo', 7: 'an integer', 'c': 12}

序列创建字典快速方式:

mapping = dict(zip(range(5), reversed(range(5))))
print(mapping)
       {0: 4, 1: 3, 2: 2, 3: 1, 4: 0}

集合是无序的不可重复的元素的集合,合并是取两个集合中不重复的元素,可以用union方法或| 运算符。交集的元素包含在两个集合中,可以用 intersection 或 & 运算符。

set([2, 2, 2, 1, 3, 3])
    {1, 2, 3}
a = {1, 2, 3, 4, 5}
b = {3, 4, 5, 6, 7, 8}
a.union(b)
     {1, 2, 3, 4, 5, 6, 7, 8}
a.intersection(b)
     {3, 4, 5}

列表推导式它允许用户方便的从一个集合过
滤元素,形成列表,在传递参数的过程中还可以修改元素

[expr for val in collection if condition]

等价于

result = []
for val in collection:
     if condition:
           result.append(expr)

举例:

strings = ['a', 'as', 'bat', 'car', 'dove', 'python']
[x.upper() for x in strings if len(x) > 2]
      ['BAT', 'CAR', 'DOVE', 'PYTHON']

lambda函数也叫做匿名函数,即函数没有具体的名称。lambda和普通函数相比,省去了函数名称,所以在使用python写脚本的时候,使用lambda可以省去定义函数的过程。lambda语句中,冒号前是参数,后是返回值。以下两个语句含义一样。

def short_function(x):
        return x * 2
equiv_anon = lambda x: x * 2

生成器迭代器的关系

生成器是构造新的可迭代对象的一种简单方式。一般的函数执行之后只会返回单个值,而生成器则是以延迟的方式返回一个值序列,即每返回一个值之后暂停,直到下一个值被请求时再继续。要创建一个生成器只需将函数中的return 替换为yield即可

def squares(n=10):
      print('Generating squares from 1 to {0}'.format(n ** 2))
      for i in range(1, n + 1):
          yield i ** 2

调用该生成器时,没有任何代码会被立即执行。

print(squares())

直到从该生成器中请求元素时,才会开始执行代码

for x in gen:
    print(x,end='')
Generating squares from 1 to 100
149162536496481100

生成器表达式这是一种类似于列表,字典,集合推导式的生成器。其创建方式为,把列表推导式两端的方括号改成圆括号

gen = (x ** 2 for x in range(100))
print(gen)
 at 0x000001D78D458DB0>

等价式:

def _make_gen():
      for x in range(100):
           yield x ** 2
gen = _make_gen()

生成器表达式也可以取代列表推导式,作为函数参数

sum(x ** 2 for x in range(100))
328350

迭代器
迭代是说一件事重复做很多次,最经典是就是for循环。for循环可以对一切有iter方法的对象进行迭代。那么一个对象是否可迭代完全取决于该对象是否有iter方法,调用对象的iter方法,就会返回一个迭代器,这个迭代器一定具有next方法,在调用这个迭代器的next方法时,迭代器就回返回它的下一个值。所以迭代器有一个很重要的特性:不可逆,只能前进不能后退。
for循环就是这样工作的,for循环在循环一个对象的时候,会调用这个对象的iter方法,得到一个迭代器,然后再调用这个迭代器的next方法去获得这个迭代器中包含的每个值。

你可能感兴趣的:(利用python进行数据分析~第三章)