【问题标题】:How to get a value from a cell of a dataframe?如何从数据框的单元格中获取值?
【发布时间】:2013-05-19 17:40:35
【问题描述】:

我已经构建了一个从我的数据框中准确提取一行的条件:

d2 = df[(df['l_ext']==l_ext) & (df['item']==item) & (df['wn']==wn) & (df['wd']==1)]

现在我想从特定列中获取一个值:

val = d2['col_name']

但结果我得到一个包含一行和一列的数据框(一个单元格)。这不是我需要的。我需要一个值(一个浮点数)。我如何在熊猫中做到这一点?

【问题讨论】:

  • 如果您尝试了其中一些答案,但最终得到了 SettingWithCopyWarning,您可以查看 this post 以了解警告和可能的解决方法/解决方案的说明。

标签: python pandas dataframe


【解决方案1】:

如果您有一个只有一行的 DataFrame,则使用 iloc 作为系列访问第一行(唯一的)行,然后使用列名访问值:

In [3]: sub_df
Out[3]:
          A         B
2 -0.133653 -0.030854

In [4]: sub_df.iloc[0]
Out[4]:
A   -0.133653
B   -0.030854
Name: 2, dtype: float64

In [5]: sub_df.iloc[0]['A']
Out[5]: -0.13365288513107493

【讨论】:

  • @Sophologist 我同意这很荒谬。当您尝试通过内联条件时,它也不起作用; my_df.loc[my_df['Col1'] == foo]['Col2'] 仍然返回 <class 'pandas.core.series.Series'> 类型的对象
  • 请注意,此解决方案返回一个系列,而不是一个值!
  • @AtteJuvonen 这取决于您的索引/列中是否有重复项(注意 at/iat 会引发重复列的异常,将提出问题)。
  • 很奇怪。我一直在阅读 loc 用于名称,iloc 用于整数,但这里 iloc 用于整数和名称
  • @mLstudent33 对行的调用是iloc,然后给出列名
【解决方案2】:

这些是标量的快速访问

In [15]: df = pandas.DataFrame(numpy.random.randn(5,3),columns=list('ABC'))

In [16]: df
Out[16]: 
          A         B         C
0 -0.074172 -0.090626  0.038272
1 -0.128545  0.762088 -0.714816
2  0.201498 -0.734963  0.558397
3  1.563307 -1.186415  0.848246
4  0.205171  0.962514  0.037709

In [17]: df.iat[0,0]
Out[17]: -0.074171888537611502

In [18]: df.at[0,'A']
Out[18]: -0.074171888537611502

【讨论】:

  • 我非常喜欢这个答案。但是,虽然您可以执行 .iloc[-1]['A'],但您无法执行 at[-1,'A'] 来获取最后一行条目
  • 这应该是答案,因为我们不会在内存中复制无用的行来只获取一个元素。
  • @hartmut 你总是可以做at[df.index[-1],'A']
【解决方案3】:

您可以将 1x1 数据框转换为 numpy 数组,然后访问该数组的第一个也是唯一的值:

val = d2['col_name'].values[0]

【讨论】:

  • 我比较喜欢这种方法,经常使用。以前也用.get_values()[0]
  • 我认为这是最好的答案,因为它不返回 pandas.series,而且是最简单的。
  • 与 Pandas 提供的方法相比,这有什么优势?
  • 在我个人看来,这是腹胀。人们应该寻找最简单的方法,并且永远不要包含不必要的框架或库,即使它们做得很好。
  • 目前在pandas中也可以使用,不需要比pandas中可用的方法有优势,它是pandas中可用的方法。
【解决方案4】:

大多数答案都使用iloc,这有利于按位置选择。

如果需要selection-by-labelloc会更方便。

用于显式获取值(相当于弃用 df.get_value('a','A'))

# this is also equivalent to df1.at['a','A']
In [55]: df1.loc['a', 'A'] 
Out[55]: 0.13200317033032932

【讨论】:

    【解决方案5】:

    不需要太复杂:

    val = df.loc[df.wd==1, 'col_name'].values[0]
    

    【讨论】:

    • 基本上是在重复 Natacha 2018 年 10 月 27 日所说的话……和 Guillaume 在 2018 年 6 月 25 日之前所说的话
    • 怎么不复杂?简单的是 df.at[r, col]
    【解决方案6】:

    我需要一个单元格的值,按列和索引名称选择。 这个解决方案对我有用:

    original_conversion_frequency.loc[1,:].values[0]

    【讨论】:

      【解决方案7】:

      看起来好像是pandas 10.1/13.1之后的变化

      在 iloc 不可用之前,我从 10.1 升级到 13.1。

      现在在 13.1 中,iloc[0]['label'] 获取单值数组而不是标量。

      像这样:

      lastprice=stock.iloc[-1]['Close']
      

      输出:

      date
      2014-02-26 118.2
      name:Close, dtype: float64
      

      【讨论】:

      • 我认为这应该只适用于具有重复条目的系列......事实上,我没有看到这一点,你能举一个小例子来证明这一点吗?
      • 我使用了 pandas 13.x,iloc[][] 或 iloc[,] 都输出一个标量。只是 iloc 不适用于负索引,例如 -1
      • 如果您能在答案中给出一个玩具示例来证明这一点,那将非常有帮助!
      【解决方案8】:

      我发现的最快/最简单的选项如下。 501代表行索引。

      df.at[501,'column_name']
      df.get_value(501,'column_name')
      

      【讨论】:

      • get_value 现已弃用(v0.21.0 RC1 (2017 年 10 月 13 日))reference is here .get_value and .set_value on Series, DataFrame, Panel, SparseSeries, and SparseDataFrame are deprecated in favor of using .iat[] or .at[] accessors (GH15269)
      【解决方案9】:

      不确定这是否是一个好习惯,但我注意到我也可以通过将系列转换为 float 来获得价值。

      例如

      rate
      

      3 0.042679

      名称:Unemployment_rate,数据类型:float64

      float(rate)
      

      0.0426789

      【讨论】:

      • 这也适用于多元素系列吗?
      【解决方案10】:

      对于pandas 0.10,其中iloc 不可用,过滤DF 并获取VALUE 列的第一行数据:

      df_filt = df[df['C1'] == C1val & df['C2'] == C2val]
      result = df_filt.get_value(df_filt.index[0],'VALUE')
      

      如果过滤的行多于 1 行,则获取第一行的值。如果过滤结果为空数据框,则会出现异常。

      【讨论】:

      • get_value 现已弃用(v0.21.0 RC1(2017 年 10 月 13 日))reference is here.get_value and .set_value on Series, DataFrame, Panel, SparseSeries, and SparseDataFrame are deprecated in favor of using .iat[] or .at[] accessors (GH15269)
      • 但是iatat无法根据列名获取值。
      【解决方案11】:
      df_gdp.columns
      

      Index([u'Country', u'Country Code', u'Indicator Name', u'Indicator Code', u'1960', u'1961', u'1962', u'1963', u'1964', u'1965', u'1966', u'1967', u'1968', u'1969', u'1970', u'1971', u'1972', u'1973', u'1974', u'1975', u'1976', u'1977', u'1978', u'1979', u'1980', u'1981', u'1982', u'1983', u'1984', u'1985', u'1986', u'1987', u'1988', u'1989', u'1990', u'1991', u'1992', u'1993', u'1994', u'1995', u'1996', u'1997', u'1998', u'1999', u'2000', u'2001', u'2002', u'2003', u'2004', u'2005', u'2006', u'2007', u'2008', u'2009', u'2010', u'2011', u'2012', u'2013', u'2014', u'2015', 你'2016'], dtype='object')

      df_gdp[df_gdp["Country Code"] == "USA"]["1996"].values[0]
      

      8100000000000.0

      【讨论】:

      • 这是答案还是问题?
      • 欢迎来到 Stack Overflow!感谢您提供代码 sn-p,它可能会提供一些有限的即时帮助。通过描述为什么这是解决问题的好方法,正确的解释将极大地改进其long-term value,并使其对有其他类似问题的未来读者更有用。请编辑您的答案以添加一些解释,包括您所做的假设。
      • 尽管投了反对票,但这个答案实际上帮助了我。
      【解决方案12】:

      将其转换为整数对我有用:

      int(sub_df.iloc[0])
      

      【讨论】:

        【解决方案13】:

        我在使用带有 MultiIndexes 的 DataFrames 时遇到过这个问题,发现 squeeze 很有用。

        来自文档:

        将一维轴对象压缩成标量。

        具有单个元素的系列或数据帧被压缩为一个标量。 具有单列或单行的 DataFrame 被压缩到一个 系列。否则对象不变。

        # example for DataFrame with MultiIndex
        > import pandas as pd
        
        > df = pd.DataFrame(
                            [
                                [1, 2, 3], 
                                [4, 5, 6], 
                                [7, 8, 9]
                            ], 
                            index=pd.MultiIndex.from_tuples( [('i', 1), ('ii', 2), ('iii', 3)] ),
                            columns=pd.MultiIndex.from_tuples( [('A', 'a'), ('B', 'b'), ('C', 'c')] )
        )
        
        > df
               A  B  C
               a  b  c
        i   1  1  2  3
        ii  2  4  5  6
        iii 3  7  8  9
        
        > df.loc['ii', 'B']
           b
        2  5
        
        > df.loc['ii', 'B'].squeeze()
        5
        

        请注意,虽然df.at[] 也可以工作(如果您不需要使用条件),但 AFAIK 仍然需要指定 MultiIndex 的所有级别。

        例子:

        > df.at[('ii', 2), ('B', 'b')]
        5
        

        我有一个具有 6 级索引和 2 级列的 DataFrame,因此只需要指定外层就很有帮助。

        【讨论】:

          【解决方案14】:

          将整行的值作为 JSON(而不是 Serie)获取:

          row = df.iloc[0]
          

          使用to_json 方法,如下所示:

          row.to_json()
          

          【讨论】:

          • 这个问题怎么涉及json?
          最近更新 更多