将给定行移动到 DataFrame 的末尾
Move given row to end of DataFrame
我想从 DataFrame 中取出给定的行并添加到相同的 DataFrame 中。
我下面的代码就是这样做的,但我不确定我的做法是否正确,或者是否有更简单、更好、更快的方法?
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)
谢谢
我可以将它简化为一行:
pd.concat([df.ix[0:1], df.ix[3:], df.ix[[2]]])
不过我没有发现您的代码和我的代码之间有任何性能差异。想必抄袭是罪魁祸首。
我会在 shift
ing 之后直接分配给 df 而不是 concat,然后使用 iloc
引用要分配行的位置,你必须调用 squeeze
这样你就可以只分配值并丢失原始索引值,否则它会引发 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
编辑
最后插入:
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
另一个更新
感谢@AsheKetchum 指出我之前的回答是错误的,现在 3 年后看这个我意识到你可以 reindex
the orig df:
如果我们将索引的副本作为 list
:
In[24]:
idx = df.index.tolist()
idx
Out[24]: [0, 1, 2, 3, 4]
然后我们可以 pop
从此列表中感兴趣的索引:
In[25]:
idx.pop(2)
idx
Out[25]: [0, 1, 3, 4]
现在我们可以 reindex
通过添加到这个列表中:
In[26]:
df.reindex([2] + idx)
Out[26]:
a
2 2
0 0
1 1
3 3
4 4
或追加:
In[27]:
df.reindex(idx+[2])
Out[27]:
a
0 0
1 1
3 3
4 4
2 2
为了提高性能,您可能需要考虑保留一个 运行 列表,其中包含要移动到 DataFrame 末尾的所有行,然后一次性将它们全部移动 pd.concat
操作。
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
我只是删除一行并在末尾追加。
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
类似于YH Wu写的,如果你知道索引(或索引),你可以在一行中完成。但是,ix 已被弃用,因此请改用 loc:
import pandas as pd
import numpy as np
df = pd.DataFrame({'a':np.arange(5)})
# a
# 0 0
# 1 1
# 2 2
# 3 3
# 4 4
# move the line with index 2 to the end:
df2 = df.drop(2).append(df.loc[2])
# a
# 0 0
# 1 1
# 3 3
# 4 4
# 2 2
# several indices, moves 3 and 2 to the end in that order:
to_move = [3, 2]
df2 = df.drop(to_move).append(df.loc[to_move])
# a
# 0 0
# 1 1
# 4 4
# 3 3
# 2 2
.drop 删除带有您作为参数给出的索引(或多个索引)的行。使用 df.loc[x],您 select 具有索引(或多个索引)x 的行。如果你写 df = df.drop... ,你直接将更改应用到原始 DataFrame。如果要重置索引,可以执行“.reset_index(drop=True)”(如果不想将原始索引保留为新列,则为 drop=True)。
我想从 DataFrame 中取出给定的行并添加到相同的 DataFrame 中。
我下面的代码就是这样做的,但我不确定我的做法是否正确,或者是否有更简单、更好、更快的方法?
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)
谢谢
我可以将它简化为一行:
pd.concat([df.ix[0:1], df.ix[3:], df.ix[[2]]])
不过我没有发现您的代码和我的代码之间有任何性能差异。想必抄袭是罪魁祸首。
我会在 shift
ing 之后直接分配给 df 而不是 concat,然后使用 iloc
引用要分配行的位置,你必须调用 squeeze
这样你就可以只分配值并丢失原始索引值,否则它会引发 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
编辑
最后插入:
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
另一个更新
感谢@AsheKetchum 指出我之前的回答是错误的,现在 3 年后看这个我意识到你可以 reindex
the orig df:
如果我们将索引的副本作为 list
:
In[24]:
idx = df.index.tolist()
idx
Out[24]: [0, 1, 2, 3, 4]
然后我们可以 pop
从此列表中感兴趣的索引:
In[25]:
idx.pop(2)
idx
Out[25]: [0, 1, 3, 4]
现在我们可以 reindex
通过添加到这个列表中:
In[26]:
df.reindex([2] + idx)
Out[26]:
a
2 2
0 0
1 1
3 3
4 4
或追加:
In[27]:
df.reindex(idx+[2])
Out[27]:
a
0 0
1 1
3 3
4 4
2 2
为了提高性能,您可能需要考虑保留一个 运行 列表,其中包含要移动到 DataFrame 末尾的所有行,然后一次性将它们全部移动 pd.concat
操作。
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
我只是删除一行并在末尾追加。
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
类似于YH Wu写的,如果你知道索引(或索引),你可以在一行中完成。但是,ix 已被弃用,因此请改用 loc:
import pandas as pd
import numpy as np
df = pd.DataFrame({'a':np.arange(5)})
# a
# 0 0
# 1 1
# 2 2
# 3 3
# 4 4
# move the line with index 2 to the end:
df2 = df.drop(2).append(df.loc[2])
# a
# 0 0
# 1 1
# 3 3
# 4 4
# 2 2
# several indices, moves 3 and 2 to the end in that order:
to_move = [3, 2]
df2 = df.drop(to_move).append(df.loc[to_move])
# a
# 0 0
# 1 1
# 4 4
# 3 3
# 2 2
.drop 删除带有您作为参数给出的索引(或多个索引)的行。使用 df.loc[x],您 select 具有索引(或多个索引)x 的行。如果你写 df = df.drop... ,你直接将更改应用到原始 DataFrame。如果要重置索引,可以执行“.reset_index(drop=True)”(如果不想将原始索引保留为新列,则为 drop=True)。