利用Python进行数据分析之Numpy学习笔记(二)

NumPy

这一篇文章主要来讲索引,但是先不直接说各种索引的用法,先胡扯会需要知道的,也不是什么重点,但是就是需要知道。没有先后顺序,就是胡扯。

以下所有的英文引用均来自官方介绍Indexing

ndarrays can be indexed using the standard Python x[obj] syntax, where x is the array and obj the selection. There are three kinds of indexing available: field access, basic slicing, advanced indexing. Which one occurs depends on obj.

格式 :x[obj] ,其中x是array,obj是选择项,一共有三种索引方式: field access, basic slicing, advanced indexing,这是官方文档的解释,和我们平时说的有些出入。

In Python, x[(exp1, exp2, ..., expN)] is equivalent to x[exp1, exp2, ..., expN]; the latter is just syntactic sugar for the former.

在Python中, x[(exp1, exp2, ..., expN)] 等效于x[exp1, exp2, ..., expN],另外在《数据分析》一书中说”x[1][2]是等效于x[1,2]的。“

All arrays generated by basic slicing are always views of the original array.

通过切片产生的数组是原始数组的视图。

Basic slicing with more than one non-: entry in the slicing tuple, acts like repeated application of slicing using a single non-: entry, where the non-: entries are successively taken (with all other non-: entries replaced by :). Thus, x[ind1,...,ind2,:] acts like x[ind1][...,ind2,:] under basic slicing.

Warning:

The above is not true for advanced indexing.

在切片元组中使用多个非:的基本切片,其行为类似于使用单个非:重复应用于切片,其中非:是被连续采用的,并且必须是在前面出现的,经测试:出现在前面失败。,x[ind1,...,ind2,:] 等效于 x[ind1][...,ind2,:]

You may use slicing to set values in the array, but (unlike lists) you can never grow the array. The size of the value to be set in x[obj] = value must be (broadcastable) to the same shape as x[obj].

通切片索引赋值,value的shape要和x[obj]的形状一致,如果一定要不同的话,那必须是可广播的,并且赋值后的shape依旧不能变化。

Advanced indexing is triggered when the selection object, obj, is a non-tuple sequence object, an ndarray (of data type integer or bool), or a tuple with at least one sequence object or ndarray (of data type integer or bool). There are two types of advanced indexing: integer and Boolean.

Advanced indexing always returns a copy of the data (contrast with basic slicing that returns a view).

这一个是高级索引的定义,也就是我们说的花式索引。高级索引的触发条件是x[obj]中的obj是一个非元组的序列对象,或者是一个数据类型是整型或布尔型的ndarray,或者是至少有一个序列对象或数据类型是整型或布尔型的ndarray的元组。

这里的翻译确实绕口,如有翻译错误,请不吝指正。最前面的那个非元组应该就是不能是纯数字的元组E.g.(2,3,4),因为元组也是一个序列对象x[(2,3,4)]就等于x[2,3,4],这就成了基本索引。

Integer array indexing

Integer array indexing allows selection of arbitrary items in the array based on their N-dimensional index. Each integer array represents a number of indexes into that dimension.

整数数组索引允许基于轴随意的选择元素,每一个整数数组代表了一些在特定维度上的索引。

Combining advanced and basic indexing

When there is at least one slice (:), ellipsis (...) or np.newaxis in the index (or the array has more dimensions than there are advanced indexes), then the behaviour can be more complicated. It is like concatenating the indexing result for each advanced index element.

当高级索引里面包含基本索引的时候如切片,那么他就像高级索引里的每一个基本索引的串联,就是在上一个索引的基础上索引,递归索引。说句实话括号里的那一句确实不知道在说什么。

下面就有一个例子,确实复杂,完全靠猜。

The easiest way to understand the situation may be to think in terms of the result shape. There are two parts to the indexing operation, the subspace defined by the basic indexing (excluding integers) and the subspace from the advanced indexing part. Two cases of index combination need to be distinguished:

  • The advanced indexes are separated by a slice, ellipsis or newaxis. For example x[arr1, :, arr2].
  • The advanced indexes are all next to each other. For example x[..., arr1, arr2, :] but not x[arr1, :, 1] since 1 is an advanced index in this regard.

In the first case, the dimensions resulting from the advanced indexing operation come first in the result array, and the subspace dimensions after that. In the second case, the dimensions from the advanced indexing operations are inserted into the result array at the same spot as they were in the initial array (the latter logic is what makes simple advanced indexing behave just like slicing).

Example

Suppose x.shape is (10,20,30) and ind is a (2,3,4)-shaped indexing intp array, then result = x[...,ind,:] has shape (10,2,3,4,30) because the (20,)-shaped subspace has been replaced with a (2,3,4)-shaped broadcasted indexing subspace. If we let i, j, k loop over the (2,3,4)-shaped subspace then result[...,i,j,k,:] = x[...,ind[i,j,k],:]. This example produces the same result as x.take(ind, axis=-2).

这个例子虽然说看不太懂吧,但是解释了我以前遇到的奇葩问题:一个3×3的数组经过一个2×2的数组索引后变成了一个2×2×3的数组,并且如果用一个自己构造的同种结构的列表数组,却是无法实现的,结果和两个数组一样。

In [62]: array
Out[62]:
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

In [63]: aa
Out[63]:
array([[1, 0],
       [0, 1]])

In [64]: array[aa]
Out[64]:
array([[[4, 5, 6],
        [1, 2, 3]],

       [[1, 2, 3],
        [4, 5, 6]]])

In [65]: array[[1,0],[0,1]]
Out[65]: array([4, 2])

In [66]: array[[[1,0],[0,1]]]
Out[66]: array([4, 2])

这个一定要有个解释的话,应该是这样的:ndarray中的每一个维度中同维度元素都是指向要索引数组同一纬度的,不想列表数组那样,第一个数组指向0轴,第二个指向1轴,不是索引递归,而是同等级的,他们选出的数组也是同等级的。这并不能看成是简单的3替换成2×2。

Boolean array indexing

This advanced indexing occurs when obj is an array object of Boolean type, such as may be returned from comparison operators.

布尔型索引发生的条件是obj是一个布尔型数组,比如可以从比较运算符返回。

其实这个布尔型索引和整数列表的高级索引是相似的。

好了不再瞎扯了,挺累的,现在开始规矩的说各种索引了,全部通过例子呈现,凡是我想到的需要注意的,都写在例子中了。

  1. 基本索引

    In [4]: arr
    Out[4]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    In [5]: arr[5]
    Out[5]: 5
    
    In [7]: arr2
    Out[7]:
    array([[0, 1, 2],
           [3, 4, 5],
           [6, 7, 8]])
    
    In [8]: arr2[1][2]
    Out[8]: 5
    
    In [9]: arr2[1,2]
    Out[9]: 5
    

    x[a][b] == x[a,b]

    通过索引列表递归索引,维度递归a索引的是最高维0轴元素,b索引的是次高维1轴元素。

  2. 切片索引

    In [10]: arr
    Out[10]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    In [11]: arr[2:5]
    Out[11]: array([2, 3, 4])
    
    In [12]: arr[2::2]
    Out[12]: array([2, 4, 6, 8])
    
    In [13]: arr2
    Out[13]:
    array([[0, 1, 2],
           [3, 4, 5],
           [6, 7, 8]])
    
    In [14]: arr2[1:]
    Out[14]:
    array([[3, 4, 5],
           [6, 7, 8]])
    
    In [15]: arr2[1:,1:]
    Out[15]:
    array([[4, 5],
           [7, 8]])
    
    In [16]: arr2[:,:1]
    Out[16]:
    array([[0],
           [3],
           [6]])
    
    In [55]: arr2
    Out[55]:
    array([[0, 1, 2],
           [3, 4, 5],
           [6, 7, 8]])
    
    In [56]: temp = arr2[2:]
    
    In [57]: temp
    Out[57]: array([[6, 7, 8]])
    
    In [58]: temp = 9
    
    In [59]: temp
    Out[59]: 9
    
    In [60]: arr2
    Out[60]:
    array([[0, 1, 2],
           [3, 4, 5],
           [6, 7, 8]])        # 这里不会发生改变,temp已经指向了新的区域
    
    In [61]: temp = arr2[2:]
    
    In [62]: temp
    Out[62]: array([[6, 7, 8]])
    
    In [63]: temp[:] = 9
    
    In [64]: temp
    Out[64]: array([[9, 9, 9]])
    
    In [65]: arr2
    Out[65]:
    array([[0, 1, 2],
           [3, 4, 5],
           [9, 9, 9]])        # 通过切片,改变temp,arr2数据也同时发生了改变。
    

    切片是在某一轴向进行横向选取,维度选定,这种的选取是同级的元素,这种选择方式似乎还会保留原数据的相对维度信息。比如切片选择一个3×3的数组的第一列,选出来的是(3,1)的数组,而基本索引选出来的是(3,)的。

    切片索引和列表索引可以叠在一起使用。

    通过第一个基本索引和这切片索引产生的数组是原数组的视图,改变视图即改变原数据。

  3. 高级索引

    1. 整数数组索引

      In [10]: arr
      Out[10]:
      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]])
      
      In [11]: arr[[5,2,1,0]]
      Out[11]:
      array([[20, 21, 22, 23],
             [ 8,  9, 10, 11],
             [ 4,  5,  6,  7],
             [ 0,  1,  2,  3]])
      
      In [12]: arr[[5,2,1,0],[2,2,1,2]]        #构成索引对
      Out[12]: array([22, 10,  5,  2])
      
      In [13]: arr[[[0,0],[5,5]],[[0,3],[0,3]]]        #选取四角元素方式一
      Out[13]:
      array([[ 0,  3],
             [20, 23]])
      
      In [14]: arr[[[0],[5]],[0,3]]        #选取四角元素方式二
      Out[14]:
      array([[ 0,  3],
             [20, 23]])
      

      整数数组索引是通过数组与数组一一对应构成索引对来选取的,每一数组代表不同轴,假如两个数组形状不同,如果这两个数组能够以广播的形式构成索引对,也是可以的。

      如果一定要选取一个区域的话可以使用高级索引+切片索引,或者使用np.ix_函数,此函数只允许传入两个一维整数数组。其实np.ix_产生的就是一个元组里面是两个array,看一下array的形状就知道np.ix_的原理了。

    2. 布尔型数组索引

      In [22]: arr
      Out[22]:
      array([[ 1.12105851,  0.27287448,  0.07762638, -0.26287726],
             [ 0.78763995, -0.48796014,  0.3238146 ,  0.22576988],
             [ 0.86004933,  1.79189963, -0.88055021, -0.1065679 ]])
      
      In [23]: arr[np.array([False,True,False])]
      Out[23]: array([[ 0.78763995, -0.48796014,  0.3238146 ,  0.22576988]])
      
      In [24]: arr[arr < 0]
      Out[24]: array([-0.26287726, -0.48796014, -0.88055021, -0.1065679 ])
      
      In [25]: arr[arr < 0] = 0        #通过布尔型数组设值
      
      In [26]: arr
      Out[26]:
      array([[ 1.12105851,  0.27287448,  0.07762638,  0.        ],
             [ 0.78763995,  0.        ,  0.3238146 ,  0.22576988],
             [ 0.86004933,  1.79189963,  0.        ,  0.        ]])
      

      通过布尔型数组选取数组中的数据,总是创建数据的副本,因为布尔型数组索引也是高级索引的一种。

    3. ndarray索引

      ndarray做索引在上文已经说明这里不再所赘述。


    还是那句话,如有不当之处,理解错误之处,欢迎指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容