我有多个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()
打印(用字母代替数字的列):
a b c d e
0 0.276383 0.655995 0.512101 0.793673 0.165763
1 0.841603 0.831268 0.776274 0.670846 0.847065
2 0.626632 0.448145 0.184613 0.763160 0.337947
3 0.502062 0.881765 0.154048 0.908834 0.669257
4 0.254717 0.538606 0.677790 0.088452 0.014447
但是,更改列顺序的操作方式不同。以下循环:
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
答案 0 :(得分:2)
使用enumerate
,并记住将其分配回您的list
:
for i, df in enumerate(dfs):
dfs[i] = df[['e', 'd', 'c', 'b', 'a']]
答案 1 :(得分:2)
我花了一段时间,实际上给了我一个很好的困惑。
之所以这样工作,是因为在第一个循环中,您修改现有对象,但是在第二个循环中,您实际上创建了 new 对象并 overwrite 旧的;这样,列表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