Move given row to end of DataFrame

微笑、不失礼 提交于 2019-12-22 10:28:02

问题


I would like to take a given row from a DataFrame and prepend or append to the same DataFrame.

My code below does just that, but I'm not sure if I'm doing it the right way or if there is an easier, better, faster way?

testdf = df.copy()
#get row 
target_row = testdf.ix[[2],:]
#del row from df
testdf.drop([testdf.index[2]], axis=0, inplace=True)
#concat original row to end or start of df
newdf = pd.concat([testdf, target_row], axis=0)

Thanks


回答1:


Rather than concat I would just assign directly to the df after shifting, then use iloc to reference the position you want to assign the row, you have to call squeeze so that you assign just the values and lose the original index value otherwise it'll raise a ValueError:

In [210]:
df = pd.DataFrame({'a':np.arange(5)})
df

Out[210]:
   a
0  0
1  1
2  2
3  3
4  4

In [206]:
target_row = df.ix[[2],:]
target_row

Out[206]:
   a
2  2

In [211]:
df = df.shift()
df.iloc[0] = target_row.squeeze()
df

Out[211]:
   a
0  2
1  0
2  1
3  2
4  3

EDIT

To insert at the end:

In [255]:
df = pd.DataFrame({'a':np.arange(5)})
target_row = df.ix[[2],:]
df = df.shift(-1)
df.iloc[-1] = target_row.squeeze()
df

Out[255]:
   a
0  1
1  2
2  3
3  4
4  2

Another update

Thanks to @AsheKetchum for pointing out that my earlier answer is incorrect, now looking at this 3 years later I realise you could just reindex the orig df:

If we take a copy of the index as a list:

In[24]:
idx = df.index.tolist()
idx

Out[24]: [0, 1, 2, 3, 4]

then we can pop the index of interest from this list:

In[25]:
idx.pop(2)
idx

Out[25]: [0, 1, 3, 4]

Now we can reindex by prepending to this list:

In[26]:
df.reindex([2] + idx)

Out[26]: 
   a
2  2
0  0
1  1
3  3
4  4

Or appending:

In[27]:    
df.reindex(idx+[2])

Out[27]: 
   a
0  0
1  1
3  3
4  4
2  2



回答2:


To improve performance, you may want to consider keeping a running list of all rows you want to move to the end of the DataFrame, and then move them all at once in a single pd.concat operation.

df = pd.DataFrame(np.random.rand(5, 3), columns=list('ABC'))
target_rows = [1, 3, 4]

a = df.iloc[[i for i in df.index if i not in target_rows], :]
b = df.iloc[target_rows, :]
>>> pd.concat([a, b])
          A         B         C
0  0.818722  0.174153  0.522383
2  0.581577  0.840306  0.985089
1  0.645752  0.238476  0.670922
3  0.198271  0.501911  0.954477
4  0.965488  0.735559  0.701077



回答3:


I can reduce it to a one-liner:

pd.concat([df.ix[0:1], df.ix[3:], df.ix[[2]]])

I don't see any performance difference between your code and mine though. Presumably the copying is the biggest culprit.




回答4:


I'd just drop a row(s) and append at the end.

df = pd.DataFrame({'a':np.arange(5)})
df.drop(2).append(df.ix[2]).reset_index(drop=True) # move 3rd row
df.drop(df.head(2).index).append(df.head(2)).reset_index() # move first 2 rows


来源:https://stackoverflow.com/questions/30940773/move-given-row-to-end-of-dataframe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!