2D Numpy数组花式索引+掩蔽

时间:2017-03-17 15:07:38

标签: python numpy multidimensional-array numpy-broadcasting

我有:

[error] /builds/foomainproject/conf/routes:5: not found: value foomodule

为什么

import numpy as np
a = np.array([[ 4, 99,  2],
              [ 3,  4, 99],
              [ 1,  8,  7],
              [ 8,  6,  8]])

等于

a[[True, True, False, False], [1,2]]

而不是

array([99, 99])

因为我使用布尔掩码选择前两行,使用花式索引选择第2和第3列?特别是自打电话以来

array([99, 2],
      [4, 99])

给了我预期的结果。我猜它的某种广播规则但对我来说并不明显。谢谢!

2 个答案:

答案 0 :(得分:3)

布尔数组或列表的计算结果好像where已将其转换为索引数组:

In [285]: a[[True,True,False,False],[1,2]]
Out[285]: array([99, 99])

In [286]: a[np.where([True,True,False,False]),[1,2]]
Out[286]: array([[99, 99]])

In [287]: np.where([True,True,False,False])
Out[287]: (array([0, 1], dtype=int32),)

In [288]: a[[0,1], [1,2]]
Out[288]: array([99, 99])

所以这是选择a[0,1]a[1,2],这是一种“成对”选择。

该块使用数组(或等效列表)进行索引,这些数组相互广播以生成(2,2)数组:

In [289]: a[np.ix_([0,1], [1,2])]
Out[289]: 
array([[99,  2],
       [ 4, 99]])
In [290]: a[[[0],[1]], [1,2]]
Out[290]: 
array([[99,  2],
       [ 4, 99]])

此案例相当于2阶段索引:a[[0,1],:][:,[1,2]]

我使用的是np版本12.布尔索引在最近的版本中有一些变化。例如,如果布尔值的长度不正确,则会运行,但会发出警告(此部分是新的)。

In [349]: a[[True,True,False],[1,2]]
/usr/local/bin/ipython3:1: VisibleDeprecationWarning: boolean index did not match indexed array along dimension 0; dimension is 4 but corresponding boolean dimension is 3
  #!/usr/bin/python3
Out[349]: array([99, 99])

第13节的变化描述于:

https://docs.scipy.org/doc/numpy-dev/release.html#boolean-indexing-changes

答案 1 :(得分:1)

我认为它的工作原理如下:

namespace MultiThreadedTest
{
    public partial class Form1 : Form
    {
        //************************************************************
        // Fields

        Thread worker = null;
        Task task = null;
        bool finished = false;


        //************************************************************
        // Constructor

        public Form1()
        {
            InitializeComponent();

            worker = new Thread(Work);
            worker.Start();

            //task = Task.Factory.StartNew(Work);
        }


        //************************************************************
        // Helper methods

        public void LogMessage(string sMessage)
        {
            LogTextBox.Text += sMessage + Environment.NewLine;
        }

        /// <summary>
        /// Threadsafe wrapper for LogMessage
        /// </summary>
        delegate void LogMessage_Delegate(string sMessage);
        public void LogMessage_Threadsafe(string sMessage)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.InvokeRequired)
            {
                Console.WriteLine("LogMessage InvokeRequired");

                LogMessage_Delegate callback = new LogMessage_Delegate(LogMessage_Threadsafe);
                this.Invoke(callback, new object[] { sMessage });
            }
            else
            {
                Console.WriteLine("LogMessage");

                LogMessage(sMessage);
            }
        }


        //************************************************************
        // Commands

        void Work()
        {
            while (!finished)
            {
                Console.WriteLine("Tread/Task Waiting...");
                LogMessage_Threadsafe("Tread/Task Waiting...");
                Thread.Sleep(1000);  // Wait a little...
            }
            Console.WriteLine("Thread/Task Done");
        }


        //************************************************************
        // Events

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            finished = true;

            if (worker != null) worker.Join();

            if (task != null) Task.WaitAll(task);

            Console.WriteLine("App Done");
        }
    }
}

现在,一旦我们用布尔掩码In [284]: a Out[284]: array([[ 4, 99, 2], [ 3, 4, 99], [ 1, 8, 7], [ 8, 6, 8]]) In [286]: bo Out[286]: array([ True, True, False, False], dtype=bool) In [287]: boc Out[287]: array([1, 2]) 索引a,我们得到:

bo

由于In [285]: a[bo] Out[285]: array([[ 4, 99, 2], [ 3, 4, 99]]) 评估为bo,因此只会选择前两行[1, 1, 0, 0]

现在,我们将aboc 组合应用于行选择掩码[1, 2]

bo

此处,掩码In [288]: a[bo, boc] Out[288]: array([99, 99]) 将应用于已获取的行。它从第一行中选择第二个元素,从第二行中选择第三个元素,产生boc

但是,有趣的是,如果你做了类似的事情:

[99, 99]

在这种情况下,numpy广播产生索引In [289]: a[1, [1, 2]] Out[289]: array([ 4, 99])