70

How do we get a particular filtered row as series?

Example dataframe:

>>> df = pd.DataFrame({'date': [20130101, 20130101, 20130102], 'location': ['a', 'a', 'c']})
>>> df
       date location
0  20130101        a
1  20130101        a
2  20130102        c

I need to select the row where location is c as a series.

I tried:

row = df[df["location"] == "c"].head(1)  # gives a dataframe
row = df.ix[df["location"] == "c"]       # also gives a dataframe with single row

In either cases I can't the row as series.

Pratyush
  • 5,108
  • 6
  • 41
  • 63
  • 1
    The answers here do work for any general case but fail to handle important corner cases. More information can be found in [this answer.](https://stackoverflow.com/a/54344511/4909087) – cs95 Jan 24 '19 at 10:35

2 Answers2

100

Use the squeeze function that will remove one dimension from the dataframe:

df[df["location"] == "c"].squeeze()
Out[5]: 
date        20130102
location           c
Name: 2, dtype: object

DataFrame.squeeze method acts the same way of the squeeze argument of the read_csv function when set to True: if the resulting dataframe is a 1-len dataframe, i.e. it has only one dimension (a column or a row), then the object is squeezed down to the smaller dimension object.

In your case, you get a Series object from the DataFrame. The same logic applies if you squeeze a Panel down to a DataFrame.

squeeze is explicit in your code and shows clearly your intent to "cast down" the object in hands because its dimension can be projected to a smaller one.

If the dataframe has more than one column or row, squeeze has no effect.

Ivan
  • 34,531
  • 8
  • 55
  • 100
Zeugma
  • 31,231
  • 9
  • 69
  • 81
  • Thanks Boud that works like a miracle. `df[df["location"] == "c"].squeeze()` too works fine. Can you please also explain what squeeze does? "squeeze length 1 dimensions" means it converts 1 row results to series? – Pratyush Oct 25 '13 at 21:29
  • @Pratyush I updated the answer above. I would recommend you call squeeze as you want to get a series from a 1D dataframe, which makes is more explicit than calling iloc[0] only for cast purposes. – Zeugma Oct 25 '13 at 21:53
  • 2
    Don't know which one is better, but squeeze like pythonic :) +1 for explanation – Roman Pekar Oct 25 '13 at 22:00
  • iloc otoh is better when resultin dataframe has more than one row – Roman Pekar Oct 25 '13 at 22:10
  • 1
    If you hav more than one row, then your df is 2D and not 1D so you cannot squeeze it – Zeugma Oct 25 '13 at 22:12
25

You can just take first row with integer indexing (iloc() function):

>>> df[df["location"] == "c"].iloc[0]
date        20130102
location           c
Name: 2, dtype: object
Roman Pekar
  • 107,110
  • 28
  • 195
  • 197
  • It is important to note that this answer does not work if you want to assign a new row here: `df[df["location"] == "c"].iloc[0] = pd.Series({'location': 'd', 'date': np.nan})` will fail. The right way to do this is to call a single slicer, once. I have added a solution [here](https://stackoverflow.com/a/54344511/4909087). – cs95 Jan 24 '19 at 10:40