¿Cómo obtener un valor de una celda de un marco de datos?

344

He construido una condición que extrae exactamente una fila de mi marco de datos:

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

Ahora me gustaría tomar un valor de una columna en particular:

val = d2['col_name']

Pero como resultado obtengo un marco de datos que contiene una fila y una columna ( es decir, una celda). No es lo que necesito. Necesito un valor (un número flotante). ¿Cómo puedo hacerlo en pandas?

romano
fuente
1
Si probó algunas de estas respuestas pero terminó con una SettingWithCopyWarning, puede consultar esta publicación para obtener una explicación de la advertencia y las posibles soluciones / soluciones.
cs95

Respuestas:

428

Si tiene un DataFrame con solo una fila, acceda a la primera (solo) fila como Serie usando iloc, y luego al valor usando el nombre de la columna:

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
Andy Hayden
fuente
1
@Sophologist mirando esto, no tengo idea. La pregunta está un poco extrañamente redactada, pero parece que la primera mitad es irrelevante para la segunda. ( ates una respuesta muy buena, aunque me parece extraño que sea ix:))
Andy Hayden
99
@Sophologist Estoy de acuerdo en que es ridículo que esto sea necesario. Tampoco funciona cuando intenta pasar los condicionales en línea; my_df.loc[my_df['Col1'] == foo]['Col2']todavía devuelve un objeto de tipo<class 'pandas.core.series.Series'>
user5359531
15
¡Tenga en cuenta que esta solución devuelve una Serie, no un valor!
Atte Juvonen
1
@AtteJuvonen Eso depende si tiene duplicados en su índice / columnas (nota en / iat plantea una excepción con columnas duplicadas, archivará un problema).
Andy Hayden
1
extraño. Sigo leyendo loc es para nombres e iloc es para enteros, pero aquí es iloc para enteros y nombres
mLstudent33
205

Estos son acceso rápido para escalares

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
Jeff
fuente
99
Me gusta mucho esta respuesta. Pero mientras que puede hacer, .iloc[-1]['A']no puede hacer at[-1,'A']para obtener la entrada de la última fila
hartmut
3
Esta debería ser la respuesta porque no copiamos en la memoria una línea inútil para obtener solo un elemento dentro.
bormat
3
@hartmut Siempre puedes hacerloat[df.index[-1],'A']
cs95
105

Puede convertir su marco de datos 1x1 en una matriz numpy, luego acceder al primer y único valor de esa matriz:

val = d2['col_name'].values[0]
Guillaume
fuente
10
Mejore la calidad de su respuesta con un poco más de explicación.
Franck Gamess
Edite su respuesta inicial con esto antes de crear un comentario. Gracias
Franck Gamess
2
Prefiero este método y lo uso con frecuencia. Solía ​​usar .get_values()[0]también.
aaronpenne
3
Creo que esta es la mejor respuesta, ya que no devuelve un pandas.series, y es la más simple.
Sean McCarthy
¿Qué ventaja tiene esto sobre los métodos proporcionados por Pandas?
AMC
28

La mayoría de las respuestas están utilizando, lo ilocque es bueno para la selección por posición.

Si necesita selección por etiqueta loc sería más conveniente.

Para obtener un valor explícitamente (equivalente a df.get_value en desuso ('a', 'A'))

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

Necesitaba el valor de una celda, seleccionada por columna y nombres de índice. Esta solución funcionó para mí:

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

Natacha
fuente
16

Parece que los cambios después de los pandas 10.1 / 13.1

Actualicé de 10.1 a 13.1, antes de que iloc no esté disponible.

Ahora con 13.1, iloc[0]['label']obtiene una matriz de valor único en lugar de un escalar.

Me gusta esto:

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

Salida:

date
2014-02-26 118.2
name:Close, dtype: float64
tiempo es amor
fuente
Creo que este solo debería ser el caso de la Serie con entradas duplicadas ... de hecho, no veo esto, ¿podría dar un pequeño ejemplo para demostrar esto?
Andy Hayden
Utilicé pandas 13.x, tanto iloc [] [] como iloc [,] muestran un escalar. solo el iloc no funciona con índice negativo, como -1
timeislove
Si puede dar un ejemplo de juguete demostrando esto en la respuesta, ¡sería realmente útil!
Andy Hayden
5

Las opciones más rápidas / fáciles que he encontrado son las siguientes. 501 representa el índice de la fila.

df.at[501,'column_name']
df.get_value(501,'column_name')
sacudidas
fuente
55
get_valuela referencia está en desuso ahora (v0.21.0 RC1 (13 de octubre de 2017)) aquí.get_value and .set_value on Series, DataFrame, Panel, SparseSeries, and SparseDataFrame are deprecated in favor of using .iat[] or .at[] accessors (GH15269)
Shihe Zhang,
4

Para pandas 0.10, donde no ilocestá disponible, filtre ay DFobtenga los datos de la primera fila de la columna VALUE:

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

Si hay más de 1 fila filtrada, obtenga el valor de la primera fila. Habrá una excepción si el filtro da como resultado un marco de datos vacío.

Sergey Sergienko
fuente
3
get_valueahora está en desuso (v0.21.0 RC1 (13 de octubre de 2017)) la referencia está aquí .get_value and .set_value on Series, DataFrame, Panel, SparseSeries, and SparseDataFrame are deprecated in favor of using .iat[] or .at[] accessors (GH15269)
Shihe Zhang
Pero iato atno puede obtener el valor basado en el nombre de la columna.
sivabudh
4

No estoy seguro si esta es una buena práctica, pero noté que también puedo obtener el valor al lanzar la serie como float.

p.ej

rate

3 0.042679

Nombre: Unemployment_rate, dtype: float64

float(rate)

0.0426789

Michael Wei
fuente
¿Funciona eso también con una serie de elementos múltiples?
Praxiteles
1

No necesita ser complicado:

val = df.loc[df.wd==1, 'col_name'].values[0]
Eduardo Freitas
fuente
-1
df_gdp.columns

Índice ([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 ', u'2016'], dtype = 'objeto')

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

8100000000000.0

Su Tingxuan
fuente
44
¿Es esta una respuesta o una pregunta?
Vega
44
¡Bienvenido a Stack Overflow! Gracias por el fragmento de código, que podría proporcionar una ayuda limitada e inmediata. Una explicación adecuada mejoraría enormemente su valor a largo plazo al describir por qué esta es una buena solución al problema, y ​​la haría más útil para futuros lectores con otras preguntas similares. Edite su respuesta para agregar alguna explicación, incluidas las suposiciones que ha hecho.
sepehr
A pesar de los votos negativos, esta respuesta realmente me ayudó.
CONvid19