Python 更改循环中数据帧中列的顺序
我有许多Python 更改循环中数据帧中列的顺序,python,pandas,dataframe,Python,Pandas,Dataframe,我有许多pandas.Dataframe对象,希望在for循环中对所有这些对象的列重新排序,但它不起作用。我得到的是: import numpy as np import pandas as pd df1 = pd.DataFrame(np.random.rand(5, 5)) df2 = pd.DataFrame(np.random.rand(5, 5)) dfs = [ df1, df2 ] 现在,更改列的名称可以起作用: for df in dfs: df.columns =
pandas.Dataframe
对象,希望在for
循环中对所有这些对象的列重新排序,但它不起作用。我得到的是:
import numpy as np
import pandas as pd
df1 = pd.DataFrame(np.random.rand(5, 5))
df2 = pd.DataFrame(np.random.rand(5, 5))
dfs = [ df1, df2 ]
现在,更改列的名称可以起作用:
for df in dfs:
df.columns = [ 'a', 'b', 'c', 'd', 'e' ]
df1.head()
打印(用字母代替数字的列):
但是,更改列的顺序的方式不同。以下循环:
for df in dfs:
df = df[ [ 'e', 'd', 'c', 'b', 'a' ] ]
保持数据帧不变
如果我在for循环之外为每个数据帧执行此操作,它会工作,不过:
df1 = df1[ [ 'e', 'd', 'c', 'b', 'a' ] ]
df1.head()
打印以下内容:
e d c b a
0 0.165763 0.793673 0.512101 0.655995 0.276383
1 0.847065 0.670846 0.776274 0.831268 0.841603
2 0.337947 0.763160 0.184613 0.448145 0.626632
3 0.669257 0.908834 0.154048 0.881765 0.502062
4 0.014447 0.088452 0.677790 0.538606 0.254717
为什么我不能在数据帧上循环以更改列顺序 如何循环列表中的数据帧以更改列顺序
使用python 3.5.3,pandas 0.23.3使用
枚举
,并记住重新分配到列表中:
for i, df in enumerate(dfs):
dfs[i] = df[['e', 'd', 'c', 'b', 'a']]
我花了一段时间在这上面,它实际上给了我一个很好的谜题。
它是这样工作的,因为在第一个循环中修改现有对象,但在第二个循环中实际创建新对象并覆盖旧对象;因此,列表dfs
将丢失对df1
和df2
的引用。如果您希望代码以第二次循环后希望看到应用于df1
和df2
的更改的方式工作,则只能使用在原始数据帧上操作且不需要覆盖的方法。
我不相信我的方式是最佳的,但这就是我的意思:
import numpy as np
import pandas as pd
df1 = pd.DataFrame(np.random.rand(5, 5))
df2 = pd.DataFrame(np.random.rand(5, 5))
dfs = [ df1, df2 ]
for df in dfs:
df.columns = [ 'a', 'b', 'c', 'd', 'e' ]
for df in dfs:
for c in ['e', 'd', 'c', 'b', 'a']:
df.insert(df.shape[1],c+'_new',df[c])
#df.drop(['e', 'd', 'c', 'b', 'a'], axis=1)
for c in [ 'a', 'b', 'c', 'd', 'e' ]:
del df[c]
df.columns = ['e', 'd', 'c', 'b', 'a']
然后调用df1
打印:
e d c b a
0 0.550885 0.879557 0.202626 0.218867 0.266057
1 0.344012 0.767083 0.139642 0.685141 0.559385
2 0.271689 0.247322 0.749676 0.903162 0.680389
3 0.643675 0.317681 0.217223 0.776192 0.665542
4 0.480441 0.981850 0.558303 0.780569 0.484447
我觉得很有趣。因此,基本上您希望迭代dfs
列表,然后在调用df1
时查看循环中所做的更改,而不是dfs[0]
,对吗?我很好奇,为什么在第一个循环中修改(即更改列的名称)可以这样工作,但重新排列列却不行。@pmarcol是的,希望在代码的后面继续使用df1
。请参见我的答案:)这似乎也不会改变原始数据帧中的列顺序(df1
,df2
)不,它不会改变原来的对象。in place
。可能需要与dfs
赋值操作相反的操作-df1,df2=dfs
在for
循环之后确实可以。@ChrisA你介意将其添加到你的答案中吗?我认为这是值得的。你的解释很好,关于修改和verwrite对象…最好能找到一种更好的方法来重新排列列,不过…是的,我也希望看到更少的“黑客”方式,但我找不到一种不需要覆盖原始对象的方法。如果你偶然发现一些重新索引
或类似的方法,记得回来编辑你的答案;)
e d c b a
0 0.550885 0.879557 0.202626 0.218867 0.266057
1 0.344012 0.767083 0.139642 0.685141 0.559385
2 0.271689 0.247322 0.749676 0.903162 0.680389
3 0.643675 0.317681 0.217223 0.776192 0.665542
4 0.480441 0.981850 0.558303 0.780569 0.484447