Python array,list,dataframe索引切片操作 2016年07月19日——智浪文档

array,list,dataframe索引切片操作 2016年07月19日——智浪文档

list,一维,二维array,datafrme,loc、iloc、ix的简单探讨

Numpy数组的索引和切片介绍:
从最基础的list索引开始讲起,我们先上一段代码和结果:

a = [0,1,2,3,4,5,6,7,8,9]
a[:5:-1]   #step < 0,所以start = 9
a[0:5:-1]  #指定了start = 0
a[1::-1]   #step < 0,所以stop = 0

输出:

[9, 8, 7, 6]
[]
[1, 0]

list切片,在“[]”中都有一般都有两个个“:”分隔符,中文意思是 [开始:结束:步长] 在上面的案例中,步长是-1所以输出的数据就倒序了。没有赋值(start,stop)就默认为0。sep默认为1且值不能为0。

a[10:20]#前11-20个数
a[:10:2]#前10个数,每两个取一个
a[::5]#所有数,每5个取一个

python切片中的高级操作:
切片的原理分析:
list的切片,内部是调用getitemsetitem,delitem和slice函数。而slice函数又是和range()函数相关的。
给切片传递的键是一个特殊的slice对象。该对象拥有可描述所请求切片方位的属性,切片的含义和演示:

>>> List4 = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
>>> x = List4[1:10] #x = List4.__getitem__(slice(1,10,None))
[2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> List4[1:5]=[100,111,122] #List4.setitem__(slice(1,3,None),100,111,122])
[1, 100, 111, 122, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
>>> del List4[1:4] #List4.del__delitem__(slice(1,4,None))
[1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
>>>

切片的边界问题:

s=[1,2,3,4]       # S 上界为 0 下界为 4
s[-100:100]       #返回 [1,2,3,4] -100超出了上界,100超出了下界:等价于 s[0:4]
s[-100:-200]      #返回 [] -100,-200均超出了上界,自动取上界:等价于s[0:0]
s[100:200]        #返回 [] 100,200均超出了下界,自动取下界值:等价于s[4:4]
s[:100]           #返回 [1,2,3,4] 开始值省略表示从第0个开始
s[0:]             #返回 [1,2,3,4] 结束值为空表示到最后一个结束

切片的扩展知识:

>>> id(List4)
140115516658320
#直接通过列表来赋值 List5 = List4,指向的内存地址空间是不变的,都是(140115516658320),无论删除List4还是List5这个列表都会被删除,即List4和List5都没有元素了。
>>> List5 = List4
>>> List5
[1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
>>> List4
[1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
>>> id(List5)
140115516658320
#但是,通过切片来命名的两个列表他们指向的内存地址编号是不同的,140115516658320 !=  140115516604784
>>> List6 = List5
>>> id(List6)
140115516658320
>>> List6 = List4[:]
>>> id(List6)
140115516604784
>>> #地址改变
...
>>>

下面们对扩展进行补充:

>>> listOfRows = [[1,2,3,4], [5,6,7,8], [9,10,11,12]]
>>> li = listOfRows
>>> id(listOfRows)
206368904L
>>> id(li)  #两者id一致,引用了同一个对象
206368904L
>>> listOfRows[:] = [[row[0], row[3], row[2]] for row in listOfRows]
>>> listOfRows
[[1, 4, 3], [5, 8, 7], [9, 12, 11]]
>>> li  #使用切片赋值,达到预期效果,同一对象跟随改变
[[1, 4, 3], [5, 8, 7], [9, 12, 11]]
>>> id(listOfRows)
206368904L
>>> id(li) #两者的id都没有变化,说明切片赋值实在原对象上修改
206368904L
>>> listOfRows = [[1,2,3,4], [5,6,7,8], [9,10,11,12]]
>>> li
[[1, 4, 3], [5, 8, 7], [9, 12, 11]]
>>> id(li)  #li没有改变
206368904L
>>> id(listOfRows)  #两者id不同,说明listOfRows绑定了一个新的对象
206412488L
>>> listOfRows
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]

直接使用 "listOfRows =" 的话,产生了一个新的对象,使用"listOfRows[:] =" 写法。简单地说,使用切片赋值可以修改原对象的类容,而不是创建一个新对象。
序列(consequence)是 python 中一种数据结构,这种数据结构根据索引来获取序列中的对象。
python 中含有六种内建序列类:list, tuple, string, unicode, buffer, xrange。其中 xrange 比较特殊,它是一个生成器,其他几个类型具有的一些序列特性对它并不适合。一般说来,具有序列结构的数据类型都可以使用:index, len, max, min, in, +, *, 切片。
list切片称为步进切片,允许使用第三个元素进行切片它的语法为sequence[起始索引:结束索引:步进值]。口诀就是:“顾头不顾尾”。假如你的第一个索引是“0”,那么你可以省略不写。
当Python使用切片语法时候就会产生切片对象。扩展的切片语法允许对不同的索引切片操作包括步进切片、多维切片和省略切片。多维切片的语法是sequence[start1:end1,start2:end2],或使用省略号,sequence[…,start1:end1]。切片对象也可以由内建函数slice()。

二维数组的选取:
首先我们前面说了 多维数组切片的语法是 sequence[start1:end1,start2:end2,…,startn:endn]
我们用一个3X3的二维数组来演示一下选取问题:

>>> b  = np.arange(9).reshape(3,3)
>>> b
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

数组下标是从0开始,对于数组a,只需要用a[m,n]选取各数组中的元素。对应的位置如下

[(0,0),(0,1),(0,2)]
[(1,0),(1,1),(1,2)]
[(2,0),(2,1),(2,2)]

对于切片二维的语法是sequence[start1:end1,start2:end2]

>>> b[1:,:2]
#先从第一个逗号分割输出从1开使行 就是  [(1,0),(1,1),(1,2)]
# 和 [(2,0),(2,1),(2,2)]
#拿第一个逗号分割的数据,在进行第二维操作,到2结束的列,输入如下
array([[3, 4],
       [6, 7]])

基于对步进切片的理解后,二维 和 三维都同样的好理解,而且没有步进那么复杂
同样可以对切片的元素进行复制操作

>>> b[1:,:2] = 1 #广播赋值
>>> b
array([[0, 1, 2],
       [1, 1, 5],
       [1, 1, 8]])
>>> b[1:,:2].shape
(2L, 2L)
>>> b[1:,:2] = np.arange(2,6).reshape(2,2) #对应赋值
>>> b
array([[0, 1, 2],
       [2, 3, 5],
       [4, 5, 8]])

三维的同理,就是sequence[start1:end1,start2:end2]。取单值的时候,a[l,m,n]。
省略的表示[:]取第n维的所有元素。

>>> b=np.arange(24).reshape(2,3,4)
>>> b[1,]
array([[12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23]])
>>> b[1,2]
array([20, 21, 22, 23])
>>> b[1,2,3]
23
>>> b[1,:,3]
array([15, 19, 23])
>>>

讲到这里,对于pandas的dataframe 我们就可以使用 iloc 把一个df 看作多维数组进行切片

>>> b  = np.arange(9).reshape(3,3)
>>> df = pd.DataFrame(b)
>>> df.iloc[1,2]
5
>>> df.iloc[1:,2]
1    5
2    8
Name: 2, dtype: int32
>>> df.iloc[1:,:2]
   0  1
1  3  4
2  6  7
>>> df.iloc[1:,:2] = 1#同样的广播赋值
>>> df
   0  1  2
0  0  1  2
1  1  1  5
2  1  1  8

(妈妈在用不用担心我的df切片了)

讲一下loc,loc 是根据index 和columns 进行选择的,在df赋值操作中,还是比较推荐这种赋值方式。

当 index 和 columns 为数值的时候 且是从0 开始我们对比一下:

>>> b = np.arange(36).reshape(6,6)
>>> b
array([[ 0,  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]])
>>> df = pd.DataFrame(b)
>>> df
    0   1   2   3   4   5
0   0   1   2   3   4   5
1   6   7   8   9  10  11
2  12  13  14  15  16  17
3  18  19  20  21  22  23
4  24  25  26  27  28  29
5  30  31  32  33  34  35
>>> df.loc[1:,:2]
    0   1   2
1   6   7   8
2  12  13  14
3  18  19  20
4  24  25  26
5  30  31  32
>>> df.iloc[1:,:2]
    0   1
1   6   7
2  12  13
3  18  19
4  24  25
5  30  31
>>> df.iloc[1,2]
8
>>> df.loc[1,2]
8
>>>

可以看到 df.loc[1:,:2] 选择了 第2 列的内容,但他的本质不是 range(0,2)他包括了结束的2。 他其实是 >= 关系。对column进行判断 取 大于等于2的列。对于不满足条件后立即终止。

>>> df.columns  =  [2,1,3,4,0,5]
>>> df
    2   1   3   4   0   5
0   0   1   2   3   4   5
1   6   7   8   9  10  11
2  12  13  14  15  16  17
3  18  19  20  21  22  23
4  24  25  26  27  28  29
5  30  31  32  33  34  35
>>> df.loc[1,2]
6
>>> df.iloc[1,2]
8
>>>
>>> df.iloc[1:,:2]
    2   1
1   6   7
2  12  13
3  18  19
4  24  25
5  30  31
>>> df.loc[1:,:2]
    2
1   6
2  12
3  18
4  24
5  30
>>>

loc 有一个好处就是你可以重新排column的顺序

>>> df.loc[:,(1,2,3,4)]
    1   2   3   4
0   1   0   2   3
1   7   6   8   9
2  13  12  14  15
3  19  18  20  21
4  25  24  26  27
5  31  30  32  33
>>> df.iloc[:,(1,2,3,4)]
    1   3   4   0
0   1   2   3   4
1   7   8   9  10
2  13  14  15  16
3  19  20  21  22
4  25  26  27  28
5  31  32  33  34
>>>

很神奇把,这个iloc就不好办了,当列名换做了 字母,loc就可以天马行空了。

ix解决混合选取的问题

>>> df.ix[:,(1,2,3,4)]
    1   2   3   4
0   1   0   2   3
1   7   6   8   9
2  13  12  14  15
3  19  18  20  21
4  25  24  26  27
5  31  30  32  33
>>> df.ix[:,:2]
    2
0   0
1   6
2  12
3  18
4  24
5  30
>>> df.ix[:,:2]

ix简单理解就是当行列都是 数字的时候 ix 随 loc。 如果都是字母的时候 ix自动判断[]内的取值,但是【行,列】不变

>>> df.loc[:2,:2]
   2
2  0
>>> df.iloc[:2,:2]
   2  1
2  0  1
1  6  7
>>> df.ix[:2,:2]
   2
2  0
>>> df.index  =  [‘a‘,‘c‘,‘d‘,‘b‘,‘e‘,‘f‘]
>>> df.ix[:2,:2]
   2
a  0
c  6
>>> df.iloc[:2,:2]
   2  1
a  0  1
c  6  7
>>> df.loc[:2,:2]  #这里loc就报错了,因为column里面没有数值类型的
Traceback (most recent call last):

讲了这么多应该能理解这些切片了

时间: 2024-10-25 15:11:01

Python array,list,dataframe索引切片操作 2016年07月19日——智浪文档的相关文章

2016年7月19日学习笔记

2016年7月19日学习笔记 计算机系统的组成部分 计算机系统由硬件系统和软件系统两大部分组成 硬件系统 冯.诺依曼体系结构: 1946年数学家冯.诺依曼提出运算器,控制器,存储器,输入设备,输出设备. 具体变现为一下硬件: 运算器,控制器  ------>  CPU 存储器          ------>  内存(断电数据清空),硬盘(可永久存储数据) 输入设备------>  键盘,鼠标等 输出设备------>  显示器 打印机等 软件系统 OS : Operating S

linux运维实战练习-2016年1月19日-2月3日课程作业(练习)安排

注:本次作业适用于就业班和套餐班. I.作业(练习)内容: 一.实战案例(练习)内容 1.描述centos6系统开机启动流程: 2.描述/etc/rc.d/sysinit脚本功能: 3.总结文本处理工具sed及awk的用法:(必须附带示例) 4.写一个脚本,生成10个随机数,并按从小到大进行排序(要求至少使用2中方法): 5.在每周二的凌晨1点5分执行脚本/data/get_username.sh,并将脚本的输出至/tmp/get_username.log日志文件中: 6.写一个脚本:如果某路径

linux运维实战练习-2016年1月19日-2月3日课程作业

I.作业(练习)内容: 1.描述centos6系统开机启动流程: a.开机BIOS加电自检测各种硬件信息 b.读取第一个可启动设备MBR,加载grub c.依据boot loader的设置初始化内核信息,内核依据initrd虚拟的磁盘和文件系统实现对根文件系统的挂载 d.切换到根文件系统, e.启动系统第一个进程init,准备好系统所需要的各项服务 f.登录界面 2.描述/etc/rc.d/sysinit脚本功能: 通过分析代码查看sysinit所具有的功能有: a.取得网络环境与主机名 b.激

2016年11月19日--连接查询,变量、if else、while

连接查询:通过连接运算符可以实现多个表查询.连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志. 常用的两个链接运算符: 1.join   on 2.union     在关系数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的所有信息存放在一个表中.当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息.连接操作给用户带来很大的灵活性,他们可以在任何时候增加新的数据类型.为不同实体创建新的表,随后通过连接进行查询. 示例一: 示例二: 示例三:

2016年11月19日 星期六 --出埃及记 Exodus 20:10

but the seventh day is a Sabbath to the LORD your God. On it you shall not do any work, neither you, nor your son or daughter, nor your manservant or maidservant, nor your animals, nor the alien within your gates. 但第七日是向耶和华你 神当守的安息日.这一日你和你的儿女,仆婢,牲畜,并

2016年10月19日

从今天起开始写从业日志,希望对以后自己的总结还是他人的工作有帮助. 今天又到浦东图书馆帮他们装mysql,他们的文档是要求装mysql cluster.后来经过沟通只要装mysql replaction就可以了. 吸取上一次的教训,需要准备的东西,先同"甲方(其实我们是来帮忙的,结果被认为是来服务的)". 主要确认的内容是:数据文件放共享存储还是本地磁盘?客户给的回复是:先放本地,到时他们自己移到共享存储上. 这个就好办了,就装两个mysql嘛. 开搞!有一台机器81还没配完,上次只装

2016年4月19日mke2fs/mks.etc3/fstab/mount指令

一.mke2fs指令mkfs.etc3 /dev/sdb1指令 主要新学习 cat /etc/filesystem  //查看文件类型 mkfs. tab键有提示    //按照系统默认的值格式化 mke2fs -b 2048 -t ext3 -m 1 -l carlton /dev/sdb1 -b 块大小 -t 文件类型 - m 留下的空间 百分之1 - l 用户名 二.mount命令磁盘的挂载和卸载 mount /dev/sdb5/  mnt 将sdb5挂在mnt分区下 df -h 看有没有

2016年4月19日

精简笔记 ? ? "你要学会精简笔记,这个过程会让你受益良多." ? ? 来自 <http://www.vccoo.com/v/ea7859> ? ? 吸气let,呼气go ? ? 我发现,吸气时说'Let'呼气时说'Go',简单,效果却颇佳 ? ? 来自 <http://www.vccoo.com/v/cbb9e0> ? ? 做计划 ? ? 对自己定的计划要求太高.还是背单词,你给自己设定了每天早上背单词的计划,可是你每天早上根本醒不来,或者说每次醒来很痛苦,

2016年10月19日--传值、传址、结构体

传值---传址 传值:将变量名中存放的值进行传输 private void 传值(int a) { a += 10; } static void Main(string[] args) { //实例化 初始化 这个类 Program hs = new Program(); int a = 0; hs.传值(a);//a不变 } 格式 传址:将这个变量名直接传输过去,若在另一边有赋值情况,这边的值会发生变化 private void 传址(int a, out int b) { b = a + 1