【问题标题】:Selection with .loc in python在 python 中使用 .loc 进行选择
【发布时间】:2017-12-07 00:37:24
【问题描述】:

我在某人的 iPython 笔记本中看到了这段代码,我对这段代码的工作原理感到非常困惑。据我了解, pd.loc[] 用作基于位置的索引器,其格式为:

df.loc[index,column_name]

但是,在这种情况下,第一个索引似乎是一系列布尔值。有人可以向我解释一下这个选择是如何工作的。我试图通读文档,但找不到解释。谢谢!

iris_data.loc[iris_data['class'] == 'versicolor', 'class'] = 'Iris-versicolor'

【问题讨论】:

    标签: python pandas dataframe ipython selection


    【解决方案1】:

    pd.DataFrame.loc 可以带一个或两个索引器。在本文的其余部分,我将第一个索引器表示为i,将第二个索引器表示为j

    如果只提供一个索引器,它适用于数据框的索引,并且假定缺少的索引器代表所有列。所以下面两个例子是等价的。

    1. df.loc[i]
    2. df.loc[i, :]

    其中: 用于表示所有列。

    如果两个索引器都存在,i 引用索引值,j 引用列值。


    现在我们可以关注ij 可以假设的值类型。让我们使用以下数据框df 作为我们的示例:

        df = pd.DataFrame([[1, 2], [3, 4]], index=['A', 'B'], columns=['X', 'Y'])
    

    loc 已经写成 ij 可以是

    1. 标量应该是各个索引对象中的值

      df.loc['A', 'Y']
      
      2
      
    2. 数组,其元素也是相应索引对象的成员(请注意,我传递给 loc 的数组的顺序受到尊重

      df.loc[['B', 'A'], 'X']
      
      B    3
      A    1
      Name: X, dtype: int64
      
      • 在传递数组时注意返回对象的维度。 i 和上面一样是一个数组,loc 返回一个对象,其中返回具有这些值的索引。在这种情况下,因为j 是一个标量,所以loc 返回一个pd.Series 对象。如果我们为ij 传递一个数组,我们可以操纵它返回一个数据帧,而该数组可能只是一个单值数组。

        df.loc[['B', 'A'], ['X']]
        
           X
        B  3
        A  1
        
    3. 布尔数组,其元素为TrueFalse,并且其长度与相应索引的长度相匹配。在这种情况下,loc 只是抓取布尔数组为True 的行(或列)。

      df.loc[[True, False], ['X']]
      
         X
      A  1
      

    除了可以传递给loc 的索引器之外,它还使您能够进行分配。现在我们可以分解您提供的代码行了。

    iris_data.loc[iris_data['class'] == 'versicolor', 'class'] = 'Iris-versicolor'
    
    1. iris_data['class'] == 'versicolor' 返回一个布尔数组。
    2. class 是一个标量,表示列对象中的值。
    3. iris_data.loc[iris_data['class'] == 'versicolor', 'class'] 返回一个 pd.Series 对象,该对象由 'class' 列组成,其中 'class''versicolor' 的所有行
    4. 与赋值运算符一起使用时:

      iris_data.loc[iris_data['class'] == 'versicolor', 'class'] = 'Iris-versicolor'
      

      我们为'class' 列中的所有元素分配'Iris-versicolor',其中'class''versicolor'

    【讨论】:

      【解决方案2】:

      这是使用 pandas 包中的数据帧。 “索引”部分可以是单个索引、索引列表或布尔值列表。这可以在文档中阅读:https://pandas.pydata.org/pandas-docs/stable/indexing.html

      所以index 部分指定要提取的行的子集,(可选)column_name 指定要从该数据帧子集中使用的列。因此,如果您想更新“类”列,但仅在类当前设置为“杂色”的行中,您可能会执行您在问题中列出的内容:

      iris_data.loc[iris_data['class'] == 'versicolor', 'class'] = 'Iris-versicolor'
      

      【讨论】:

        【解决方案3】:

        这是一个 pandas 数据框,它使用带有df.loc 的标签库选择工具,其中有两个输入,一个用于行,另一个用于列,因此在行输入中它选择了所有这些行值,其中保存在列class 中的值为versicolor,在列输入中选择标签为class 的列,并为它们分配Iris-versicolor 值。 所以基本上它用Iris-versicolor替换了class列的所有单元格versicolor

        【讨论】:

          【解决方案4】:
          1. 只要可以使用slicing (a:n),就可以将其替换为fancy indexing(例如[a,b,c,...,n])。花式索引只不过是明确列出所有索引值,而不是仅指定限制。

          2. 只要可以使用花哨的索引,就可以将其替换为与索引大小相同的布尔值列表(mask)。对于本应包含在精美索引中的索引值,该值为True,对于本应排除的值,该值为False。这是列出一些索引值的另一种方式,但可以在 NumPy 和 Pandas 中轻松自动化,例如通过逻辑比较(如您的情况)。

          第二种替换可能性是您的示例中使用的那种。在:

          iris_data.loc[iris_data['class'] == 'versicolor', 'class'] = 'Iris-versicolor'
          

          面具

          iris_data['class'] == 'versicolor'
          

          是一个长而愚蠢的索引的替代品,它将是行号列表,其中class 列(一个系列)具有值versicolor

          布尔掩码是出现在.iloc.loc(例如df.loc[mask])索引器中还是直接作为索引(例如df[mask])取决于是否允许切片作为直接索引。此类情况显示在以下索引器备忘单中:


          Pandas 索引器 loc 和 iloc 备忘单

          【讨论】:

            【解决方案5】:

            这是pandas 基于标签的选择,如下所述:https://pandas.pydata.org/pandas-docs/stable/indexing.html#selection-by-label

            布尔数组基本上是一种使用掩码的选择方法。

            【讨论】:

              猜你喜欢
              • 2020-04-02
              • 2017-03-05
              • 2018-12-04
              • 2018-08-18
              • 2016-10-24
              • 2012-02-13
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多