Pandas - Get first row value of a given column Pandas - Get first row value of a given column python python

Pandas - Get first row value of a given column


To select the ith row, use iloc:

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

To select the ith value in the Btime column you could use:

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

There is a difference between df_test['Btime'].iloc[0] (recommended) and df_test.iloc[0]['Btime']:

DataFrames store data in column-based blocks (where each block has a singledtype). If you select by column first, a view can be returned (which isquicker than returning a copy) and the original dtype is preserved. In contrast,if you select by row first, and if the DataFrame has columns of differentdtypes, then Pandas copies the data into a new Series of object dtype. Soselecting columns is a bit faster than selecting rows. Thus, althoughdf_test.iloc[0]['Btime'] works, df_test['Btime'].iloc[0] is a little bitmore efficient.

There is a big difference between the two when it comes to assignment.df_test['Btime'].iloc[0] = x affects df_test, but df_test.iloc[0]['Btime']may not. See below for an explanation of why. Because a subtle difference inthe order of indexing makes a big difference in behavior, it is better to use single indexing assignment:

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

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

The recommended way to assign new values to aDataFrame is to avoid chained indexing, and instead use the method shown byandrew,

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

or

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

The latter method is a bit faster, because df.loc has to convert the row and column labels topositional indices, so there is a little less conversion necessary if you usedf.iloc instead.


df['Btime'].iloc[0] = x works, but is not recommended:

Although this works, it is taking advantage of the way DataFrames are currently implemented. There is no guarantee that Pandas has to work this way in the future. In particular, it is taking advantage of the fact that (currently) df['Btime'] always returns aview (not a copy) so df['Btime'].iloc[n] = x can be used to assign a new valueat the nth location of the Btime column of df.

Since Pandas makes no explicit guarantees about when indexers return a view versus a copy, assignments that use chained indexing generally always raise a SettingWithCopyWarning even though in this case the assignment succeeds in modifying df:

In [22]: df = pd.DataFrame({'foo':list('ABC')}, index=[0,2,1])In [24]: df['bar'] = 100In [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 DataFrameSee 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]: dfOut[26]:   foo  bar0   A   99  <-- assignment succeeded2   B  1001   C  100

df.iloc[0]['Btime'] = x does not work:

In contrast, assignment with df.iloc[0]['bar'] = 123 does not work because df.iloc[0] is returning a copy:

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 DataFrameSee the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copyIn [67]: dfOut[67]:   foo  bar0   A   99  <-- assignment failed2   B  1001   C  100

Warning: I had previously suggested df_test.ix[i, 'Btime']. But this is not guaranteed to give you the ith value since ix tries to index by label before trying to index by position. So if the DataFrame has an integer index which is not in sorted order starting at 0, then using ix[i] will return the row labeled i rather than the ith row. For example,

In [1]: df = pd.DataFrame({'foo':list('ABC')}, index=[0,2,1])In [2]: dfOut[2]:   foo0   A2   B1   CIn [4]: df.ix[1, 'foo']Out[4]: 'C'


Note that the answer from @unutbu will be correct until you want to set the value to something new, then it will not work if your dataframe is a view.

In [4]: df = pd.DataFrame({'foo':list('ABC')}, index=[0,2,1])In [5]: df['bar'] = 100In [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 DataFrameSee 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)

Another approach that will consistently work with both setting and getting is:

In [7]: df.loc[df.index[0], 'foo']Out[7]: 'A'In [8]: df.loc[df.index[0], 'bar'] = 99In [9]: dfOut[9]:  foo  bar0   A   992   B  1001   C  100


Another way to do this:

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

This way seems to be faster than using .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)