88

I have a DataFrame object similar to this one:

       onset    length
1      2.215    1.3
2     23.107    1.3
3     41.815    1.3
4     61.606    1.3
...

What I would like to do is insert a row at a position specified by some index value and update the following indices accordingly. E.g.:

       onset    length
1      2.215    1.3
2     23.107    1.3
3     30.000    1.3  # new row
4     41.815    1.3
5     61.606    1.3
...

What would be the best way to do this?

Troas
  • 1,007
  • 1
  • 9
  • 9
  • Possible to add row at particular index: `df1 = pd.DataFrame(np.insert(df1.values, index+1, values=[" "] * len(df1.columns), axis=0),columns = df1.columns)` – Anonymous Feb 01 '19 at 09:51
  • You could also take the transpose and find the respective columns instead. –  Mar 02 '19 at 09:26

5 Answers5

84

You could slice and use concat to get what you want.

line = DataFrame({"onset": 30.0, "length": 1.3}, index=[3])
df2 = concat([df.iloc[:2], line, df.iloc[2:]]).reset_index(drop=True)

This will produce the dataframe in your example output. As far as I'm aware, concat is the best method to achieve an insert type operation in pandas, but admittedly I'm by no means a pandas expert.

bdiamante
  • 13,894
  • 5
  • 37
  • 45
  • 1
    @bdiamante Hi, please have a look at this question here https://stackoverflow.com/questions/44599589/inserting-new-rows-in-pandas-data-frame-at-specific-indices – Liza Jun 21 '17 at 21:53
  • @bdiamante it is replacing the row at index 3 when trying to insert a new row a index 3. How can keep the existing row at index 3 and at a new row after that? – Shashank Shekher Apr 03 '20 at 18:57
37

I find it more readable to sort rather than slice and concatenate.

line = DataFrame({"onset": 30.0, "length": 1.3}, index=[2.5])
df = df.append(line, ignore_index=False)
df = df.sort_index().reset_index(drop=True)
Reimar
  • 2,248
  • 1
  • 17
  • 15
25

I think it's even easier without concat or append:

df.loc[2.5] = 30.0, 1.3
df = df.sort_index().reset_index(drop=True)

(Supposing that the index is as provided, starting from 1)

SergioGM
  • 420
  • 4
  • 7
2
line = DataFrame({"onset": 30.0, "length": 1.3}, index=[3])
df2 = concat([df.iloc[:2], line, df.iloc[3:]]).reset_index(drop=True)

this solution is replacing that index values i want to just add one index without replacing the index values.

Shayki Abramczyk
  • 30,710
  • 15
  • 70
  • 94
0

If you want to keep the original indexes this might work beter:

df = pd.DataFrame(dict(x=[0, 1, 2, 3, 4]))
df_update = pd.DataFrame(dict(x=[10, 11, 12]), index=[3, 4, 5])

# concat df_update first
df = pd.concat([df_update, df], axis=0)

# drop duplicates, updates will be prioritized
df = df.iloc[df.index.drop_duplicates()]

# sort to regain order
df.sort_index(inplace=True)
Cristian Garcia
  • 9,350
  • 5
  • 51
  • 72