如何从数据框架的单元格中获取值?

我构造了一个条件,从我的数据帧中提取一行:

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

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

val = d2['col_name']

但结果是,我得到的数据帧只包含一行和一列(即一个单元格)。这不是我需要的。我需要一个值(一个浮点数)。在熊猫身上怎么做呢?

2086036 次浏览

如果你有一个只有一行的DataFrame,那么使用iloc访问第一行作为一个Series,然后使用列名访问值:

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

这些是标量的快速访问方法:

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

看起来像是熊猫10.1或13.1之后的变化。

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

现在使用13.1,iloc[0]['label']将获得一个值数组,而不是一个标量。

是这样的:

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

输出:

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

对于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')

如果过滤了多个行,则获取第一行的值。如果筛选结果为空数据帧,则会出现异常。

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

例如,

rate

3 0.042679

名称:Unemployment_rate, dtype: float64

float(rate)

0.0426789

我所找到的最快和最简单的方法如下。501表示行索引。

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

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

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

显式获取值(相当于已弃用 df.get_value (' a ', ' ')) < / p >

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

你可以把你的1x1数据帧转换成一个NumPy数组,然后访问该数组的第一个也是唯一的值:

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

指数([u'国家',u'国家代码',u'指标名称',u'指标代码', u ' 1960 ', ' 1961 ',你‘1962’,‘1963’,‘1964’,‘1965’,‘1966’,‘1967’, u ' 1968 ', ' 1969 ',你‘1970’,‘1971’,‘1972’,‘1973’,‘1974’,‘1975’, u ' 1976 ', ' 1977 ',你‘1978’,‘1979’,‘1980’,‘1981’,‘1982’,‘1983’, u ' 1984 ', ' 1985 ',你‘1986’,‘1987’,‘1988’,‘1989’,‘1990’,‘1991’, u ' 1992 ', ' 1993 ',你‘1994’,‘1995’,‘1996’,‘1997’,‘1998’,‘1999’, u ' 2000 ', ' 2001 ',你‘2002’,‘2003’,‘2004’,‘2005’,‘2006’,‘2007’, u ' 2008 ', ' 2009 ',你‘2010’,‘2011’,‘2012’,‘2013’,‘2014’,‘2015’, u ' 2016 '), dtype = '对象')< / p >

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

8100000000000.0

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

# EYZ0

这并不需要太复杂:

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

要获得完整行的值为JSON(而不是一个Serie):

row = df.iloc[0]

使用to_json方法,如下所示:

row.to_json()

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

int(sub_df.iloc[0])

我在使用MultiIndexes的dataframes时遇到过这个问题,发现挤压很有用。

从文档中可以看到:

将1维轴对象挤压成标量。

包含单个元素的系列或dataframe被压缩为标量。 具有单列或单行的数据帧被压缩到a 系列。

.否则对象不变
# Example for a 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[]也可以工作(如果你不需要使用条件),但你仍然需要指定MultiIndex的所有级别。

例子:

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

我有一个六层索引和两层列的数据框架,所以只需要指定外层是非常有用的。

在以后的版本中,你可以简单地这样做来修复它:

val = float(d2['col_name'].iloc[0])

使用.item()返回一个标量(不是Series),如果选择了单个元素,则使用只有。它比.values[0]安全得多,.values[0]无论选择多少个元素都将返回第一个元素。

>>> df = pd.DataFrame({'a': [1,2,2], 'b': [4,5,6]})
>>> df[df['a'] == 1]['a']  # Returns a Series
0    1
Name: a, dtype: int64
>>> df[df['a'] == 1]['a'].item()
1
>>> df2 = df[df['a'] == 2]
>>> df2['b']
1    5
2    6
Name: b, dtype: int64
>>> df2['b'].values[0]
5
>>> df2['b'].item()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3/dist-packages/pandas/core/base.py", line 331, in item
raise ValueError("can only convert an array of size 1 to a Python scalar")
ValueError: can only convert an array of size 1 to a Python scalar