Saltar al contenido

Pandas: obtiene el valor de la primera fila de una columna determinada

Solución:

Para seleccionar el ith fila, uso 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

Para seleccionar el iésimo valor en el Btime columna que podría usar:

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

Hay una diferencia entre df_test['Btime'].iloc[0] (recomendado) y df_test.iloc[0]['Btime']:

Los DataFrames almacenan datos en bloques basados ​​en columnas (donde cada bloque tiene un solo dtype). Si selecciona por columna primero, un vista se puede devolver (que es más rápido que devolver una copia) y se conserva el tipo d original. Por el contrario, si selecciona primero por fila, y si el DataFrame tiene columnas de diferentes tipos de datos, entonces Pandas copias los datos en una nueva serie de dtype de objeto. Por lo tanto, seleccionar columnas es un poco más rápido que seleccionar filas. Así, aunque
df_test.iloc[0]['Btime'] obras, df_test['Btime'].iloc[0] es un poco más eficiente.

Hay una gran diferencia entre los dos cuando se trata de asignación.
df_test['Btime'].iloc[0] = x afecta df_test, pero df_test.iloc[0]['Btime']
podría no. Consulte a continuación para obtener una explicación de por qué. Debido a que una sutil diferencia en el orden de indexación marca una gran diferencia en el comportamiento, es mejor usar una asignación de indexación única:

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

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

los forma recomendada asignar nuevos valores a un DataFrame es evitar la indexación encadenada y, en su lugar, utilizar el método mostrado por andrew,

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

o

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

El último método es un poco más rápido, porque df.loc tiene que convertir las etiquetas de fila y columna en índices posicionales, por lo que se necesita un poco menos de conversión si usa
df.iloc en lugar de.


df['Btime'].iloc[0] = x funciona, pero no se recomienda:

Aunque esto funciona, está aprovechando la forma en que los DataFrames son en la actualidad implementado. No hay garantía de que Pandas tenga que funcionar de esta manera en el futuro. En particular, se aprovecha del hecho de que (actualmente) df['Btime'] siempre devuelve una vista (no una copia) por lo que df['Btime'].iloc[n] = x puede ser usado para asignar un nuevo valor en la enésima ubicación del Btime columna de df.

Dado que Pandas no ofrece garantías explícitas sobre cuándo los indexadores devuelven una vista frente a una copia, las asignaciones que utilizan la indexación encadenada generalmente siempre generan una SettingWithCopyWarning aunque en este caso la asignación logra modificar df:

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 No funciona:

Por el contrario, la asignación con df.iloc[0]['bar'] = 123 no funciona porque df.iloc[0] está devolviendo una copia:

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

Advertencia: Yo había sugerido previamente df_test.ix[i, 'Btime']. Pero esto no está garantizado para darle la ith valor desde ix intenta indexar por etiqueta antes de intentar indexar por posición. Entonces, si el DataFrame tiene un índice entero que no está ordenado a partir de 0, entonces use ix[i] devolverá la fila etiquetado i en lugar del ith hilera. Por ejemplo,

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'

Tenga en cuenta que la respuesta de @unutbu será correcta hasta que desee establecer el valor en algo nuevo, entonces no funcionará si su marco de datos es una vista.

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)

Otro enfoque que funcionará consistentemente tanto con la configuración como con la obtención es:

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

Otra forma de hacer esto:

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

De esta manera parece ser más rápido que usar .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)
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *