Is it possible to insert a row at an arbitrary position in a dataframe using pandas?
Question:
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?
Answers:
You could slice and use concat to get what you want.
from pandas import DataFrame, concat
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.
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)
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)
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)
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?
You could slice and use concat to get what you want.
from pandas import DataFrame, concat
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.
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)
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)
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)