代码之家  ›  专栏  ›  技术社区  ›  Ahmed Haque

获取给定列的第一行值

  •  496
  • Ahmed Haque  · 技术社区  · 10 年前

    这似乎是一个可笑的简单问题。。。但我没有看到我期待的简单答案。

    那么,如何在Pandas中获取给定列的第n行的值?(我对第一行特别感兴趣,但也会对更普遍的做法感兴趣)。

    例如,假设我想将1.2值 Btime 作为变量。

    做这件事的正确方法是什么?

    >>> df_test
        ATime   X   Y   Z   Btime  C   D   E
    0    1.2  2  15   2    1.2  12  25  12
    1    1.4  3  12   1    1.3  13  22  11
    2    1.5  1  10   6    1.4  11  20  16
    3    1.6  2   9  10    1.7  12  29  12
    4    1.9  1   1   9    1.9  11  21  19
    5    2.0  0   0   0    2.0   8  10  11
    6    2.4  0   0   0    2.4  10  12  15
    
    10 回复  |  直到 2 年前
        1
  •  777
  •   unutbu    5 年前

    要选择 ith 一行 use iloc :

    In [31]: df_test.iloc[0]
    Out[31]: 
    ATime     1.2
    X         2.0
    Y        15.0
    Z         2.0
    Btime     1.2
    C        12.0
    D        25.0
    E        12.0
    Name: 0, dtype: float64
    

    Btime 可以使用的列:

    In [30]: df_test['Btime'].iloc[0]
    Out[30]: 1.2
    

    两者之间存在差异 df_test['Btime'].iloc[0] (推荐)和 df_test.iloc[0]['Btime'] :

    DataFrames将数据存储在基于列的块中(每个块都有一个 dtype)。如果先按列选择 看法 可以返回(即 比返回副本更快),并且保留原始dtype。相反 如果首先按行选择,并且DataFrame具有不同的列 dtypes,然后是Pandas 副本 将数据转换为新的对象数据类型系列。所以 选择列比选择行快一点。因此,尽管 df_测试iloc[0]['Btime'] 作品 df_测试['Btime'].iloc[0] 有一点点 更高效。

    当涉及到任务时,两者之间有很大的区别。 df_test['Btime'].iloc[0] = x 影响 df_test 但是 df_测试iloc[0]['Btime'] 可能不会。有关原因的解释,请参见下文。因为 索引的顺序对行为有很大的影响,最好使用单个索引分配:

    df.iloc[0, df.columns.get_loc('Btime')] = x
    

    df.iloc[0, df.columns.get_loc('Btime')] = x (推荐):

    这个 recommended way 将新值分配给 DataFrame将 avoid chained indexing ,并改用该方法 shown by andrew ,

    df.loc[df.index[n], 'Btime'] = x
    

    df.iloc[n, df.columns.get_loc('Btime')] = x
    

    后一种方法更快,因为 df.loc 必须将行和列标签转换为 位置索引,因此如果使用 df.iloc 相反


    df['Btime'].iloc[0] = x 有效,但不建议:

    虽然这是有效的,但它利用了DataFrames 目前 实施。不能保证熊猫将来一定会这样做。特别是,它利用了(目前) df['Btime'] 始终返回 查看(不是副本) df['Btime'].iloc[n] = x 可以用于 分配 一个新的值 位于 B时间 第列,共列 df .

    由于Pandas没有明确保证索引器何时返回视图而不是副本,因此使用链式索引的赋值通常会引发 SettingWithCopyWarning 即使在这种情况下,赋值成功修改 东风 :

    In [22]: df = pd.DataFrame({'foo':list('ABC')}, index=[0,2,1])
    In [24]: df['bar'] = 100
    In [25]: df['bar'].iloc[0] = 99
    /home/unutbu/data/binky/bin/ipython:1: SettingWithCopyWarning: 
    A value is trying to be set on a copy of a slice from a DataFrame
    
    See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
      self._setitem_with_indexer(indexer, value)
    
    In [26]: df
    Out[26]: 
      foo  bar
    0   A   99  <-- assignment succeeded
    2   B  100
    1   C  100
    

    df.iloc[0]['Btime'] = x 不工作:

    相反,使用 df.iloc[0]['bar'] = 123 不起作用,因为 df.iloc[0] 正在返回副本:

    In [66]: df.iloc[0]['bar'] = 123
    /home/unutbu/data/binky/bin/ipython:1: SettingWithCopyWarning: 
    A value is trying to be set on a copy of a slice from a DataFrame
    
    See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
    
    In [67]: df
    Out[67]: 
      foo  bar
    0   A   99  <-- assignment failed
    2   B  100
    1   C  100
    

    警告 :我以前建议过 df_test.ix[i, 'Btime'] 。但这不能保证给你 第i个 ix 尝试按索引 标签 在尝试索引之前 位置 。因此,如果DataFrame有一个整数索引,该索引的排序顺序从0开始,则使用 ix[i] 将返回该行 标记 i 而不是 第i个 一行例如

    In [1]: df = pd.DataFrame({'foo':list('ABC')}, index=[0,2,1])
    
    In [2]: df
    Out[2]: 
      foo
    0   A
    2   B
    1   C
    
    In [4]: df.ix[1, 'foo']
    Out[4]: 'C'
    
        2
  •  37
  •   andrew    9 年前

    请注意,在您想将值设置为新值之前,@unaubu的答案将是正确的,如果您的数据帧是一个视图,那么它将不起作用。

    In [4]: df = pd.DataFrame({'foo':list('ABC')}, index=[0,2,1])
    In [5]: df['bar'] = 100
    In [6]: df['bar'].iloc[0] = 99
    /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas-0.16.0_19_g8d2818e-py2.7-macosx-10.9-x86_64.egg/pandas/core/indexing.py:118: SettingWithCopyWarning:
    A value is trying to be set on a copy of a slice from a DataFrame
    
    See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
      self._setitem_with_indexer(indexer, value)
    

    另一种可以在设置和获取过程中始终有效的方法是:

    In [7]: df.loc[df.index[0], 'foo']
    Out[7]: 'A'
    In [8]: df.loc[df.index[0], 'bar'] = 99
    In [9]: df
    Out[9]:
      foo  bar
    0   A   99
    2   B  100
    1   C  100
    
        3
  •  35
  •   Abdulrahman Bres Cristiana Chavez    6 年前

    另一种方法是:

    first_value = df['Btime'].values[0]
    

    这种方式似乎比使用 .iloc :

    In [1]: %timeit -n 1000 df['Btime'].values[20]
    5.82 µs ± 142 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    
    In [2]: %timeit -n 1000 df['Btime'].iloc[20]
    29.2 µs ± 1.28 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    
        4
  •  14
  •   pacholik    7 年前
    1. df.iloc[0].head(1) -仅来自整个第一行的第一个数据集。
    2. df.iloc[0] -整个列中的第一行。
        5
  •  12
  •   DINA TAKLIT    5 年前

    一般来说,如果你想选择第一个 N行 来自 J柱 从…起 pandas dataframe 最好的方法是:

    data = dataframe[0:N][:,J]
    
        6
  •  11
  •   Mykola Zotko    2 年前

    要访问单个值,可以使用以下方法 iat 那就是 much faster iloc :

    df['Btime'].iat[0]
    

    您也可以使用该方法 take :

    df['Btime'].take(0)
    
        7
  •  8
  •   cottontail    2 年前

    .iat .at 是获取和设置单个值的方法,比 .iloc .loc 。Mykola Zotko在他们的回答中指出了这一点,但他们没有使用 .iat公司 充分发挥其作用。

    当我们可以使用 .iat公司 ,我们应该只需要索引到数据帧一次。

    这不太好:

    df['Btime'].iat[0]
    

    这并不理想,因为“Btime”列首先被选为一个系列,然后 .iat公司 用于索引到该系列中。

    这两个选项是最好的:

    1. 使用零索引位置:
      df.iat[0, 4]  # get the value in the zeroth row, and 4th column
      
    2. 使用标签:
       df.at[0, 'Btime']  # get the value where the index label is 0 and the column name is "Btime".
      

    两种方法都返回值1.2。

        8
  •  7
  •   Alex Ortner    5 年前

    例如,要从列“test”和行1中获取值,其工作方式如下

    df[['test']].values[0][0]
    

    仅作为 df[['test']].values[0] 返回一个数组

        9
  •  2
  •   Hunaphu    5 年前

    获取第一行并保留索引的另一种方法:

    x = df.first('d') # Returns the first day. '3d' gives first three days.
    
        10
  •  0
  •   cottontail    2 年前

    根据 pandas docs , at 是访问标量值(如OP中的用例)的最快方法(已由 Alex 在本页上)。

    基于Alex的回答,因为数据帧不一定有范围索引,所以索引可能更完整 df.index (由于数据帧索引构建在numpy数组上,因此可以像数组一样对其进行索引)或调用 get_loc() 以获取列的整数位置。

    df.at[df.index[0], 'Btime']
    df.iat[0, df.columns.get_loc('Btime')]
    

    一个常见的问题是,如果您使用布尔掩码获取单个值,但最终得到一个带索引的值(实际上是一个系列);例如。:

    0    1.2
    Name: Btime, dtype: float64
    

    你可以使用 squeeze() 获取标量值,即。

    df.loc[df['Btime']<1.3, 'Btime'].squeeze()