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