将列按名称移动到pandas中的表格前面

时间:2014-08-04 15:21:32

标签: python pandas move dataframe shift

这是我的df:

                             Net   Upper   Lower  Mid  Zsore
Answer option                                                
More than once a day          0%   0.22%  -0.12%   2    65 
Once a day                    0%   0.32%  -0.19%   3    45
Several times a week          2%   2.45%   1.10%   4    78
Once a week                   1%   1.63%  -0.40%   6    65

如何将列名(“Mid”)移动到表格的前面,索引为0.这就是它需要的样子:

                             Mid   Upper   Lower  Net  Zsore
Answer option                                                
More than once a day          2   0.22%  -0.12%   0%    65 
Once a day                    3   0.32%  -0.19%   0%    45
Several times a week          4   2.45%   1.10%   2%    78
Once a week                   6   1.63%  -0.40%   1%    65

我当前的代码通过“df.columns.tolist()”按索引移动列,但我喜欢按名称移动它。

11 个答案:

答案 0 :(得分:70)

我们可以通过传递列表来使用ix重新排序:

In [27]:
# get a list of columns
cols = list(df)
# move the column to head of list using index, pop and insert
cols.insert(0, cols.pop(cols.index('Mid')))
cols
Out[27]:
['Mid', 'Net', 'Upper', 'Lower', 'Zsore']
In [28]:
# use ix to reorder
df = df.ix[:, cols]
df
Out[28]:
                      Mid Net  Upper   Lower  Zsore
Answer_option                                      
More_than_once_a_day    2  0%  0.22%  -0.12%     65
Once_a_day              3  0%  0.32%  -0.19%     45
Several_times_a_week    4  2%  2.45%   1.10%     78
Once_a_week             6  1%  1.63%  -0.40%     65

另一种方法是对列进行引用并将其重新插入前面:

In [39]:
mid = df['Mid']
df.drop(labels=['Mid'], axis=1,inplace = True)
df.insert(0, 'Mid', mid)
df
Out[39]:
                      Mid Net  Upper   Lower  Zsore
Answer_option                                      
More_than_once_a_day    2  0%  0.22%  -0.12%     65
Once_a_day              3  0%  0.32%  -0.19%     45
Several_times_a_week    4  2%  2.45%   1.10%     78
Once_a_week             6  1%  1.63%  -0.40%     65

您也可以使用loc来获得相同的结果,ix将在0.20.0之后的未来版本的pandas中弃用:

df = df.loc[:, cols]

答案 1 :(得分:30)

您可以在pandas中使用df.reindex()函数。 df是

                      Net  Upper   Lower  Mid  Zsore
Answer option                                      
More than once a day  0%  0.22%  -0.12%    2     65
Once a day            0%  0.32%  -0.19%    3     45
Several times a week  2%  2.45%   1.10%    4     78
Once a week           1%  1.63%  -0.40%    6     65

定义列名列表

cols = df.columns.tolist()
cols
Out[13]: ['Net', 'Upper', 'Lower', 'Mid', 'Zsore']

将列名移动到您想要的位置

cols.insert(0, cols.pop(cols.index('Mid')))
cols
Out[16]: ['Mid', 'Net', 'Upper', 'Lower', 'Zsore']

然后使用df.reindex()函数重新排序

df = df.reindex(columns= cols)

out put是:df

                      Mid  Upper   Lower Net  Zsore
Answer option                                      
More than once a day    2  0.22%  -0.12%  0%     65
Once a day              3  0.32%  -0.19%  0%     45
Several times a week    4  2.45%   1.10%  2%     78
Once a week             6  1.63%  -0.40%  1%     65

答案 2 :(得分:12)

我不喜欢我必须在其他解决方案中明确指定所有其他列,所以这对我来说效果最好。虽然对于大型数据帧来说可能会很慢......?

df.set_index('Mid').reset_index()

答案 3 :(得分:5)

这是我经常用于重新排列列位置的一组通用代码。您可能会发现它有用。

cols = df.columns.tolist()
n = int(cols.index('Mid'))
cols = [cols[n]] + cols[:n] + cols[n+1:]
df = df[cols]

答案 4 :(得分:4)

也许我遗漏了一些东西,但是其中许多答案似乎过于复杂。您应该只需要在一个列表中设置列即可:

最前面的列

df = df[ ['Mid'] + [ col for col in df.columns if col != 'Mid' ] ]

或者,如果您想将其移至背面:

df = df[ [ col for col in df.columns if col != 'Mid' ] + ['Mid'] ]

或者如果您想移动不止一列:

cols_to_move = ['Mid', 'Zsore']
df           = df[ cols_to_move + [ col for col in df.columns if col not in cols_to_move ] ]

答案 5 :(得分:4)

我更喜欢这种解决方案:

col = df.pop("Mid")
df = df.insert(0, col.name, col)

与其他建议的答案相比,它更易于阅读且速度更快。

def move_column_inplace(df, col, pos):
    col = df.pop(col)
    df.insert(pos, col.name, col)

性能评估:

对于此测试,当前的最后一列在每次重复中都移到最前面。就地方法通常表现更好。尽管citynorman的解决方案可以就地完成,但基于.loc的Ed Chum方法和基于reindex的sachinnm方法却不能。

虽然其他方法是通用的,但citynorman的解决方案仅限于pos=0。我没有发现df.loc[cols]df[cols]之间的性能差异,这就是为什么我没有包含其他建议的原因。

我在MacBook Pro(2015年中)上使用python 3.6.8和pandas 0.24.2进行了测试。

import numpy as np
import pandas as pd

n_cols = 11
df = pd.DataFrame(np.random.randn(200000, n_cols),
                  columns=range(n_cols))

def move_to_front_normanius_inplace(df):
    move_column_inplace(df, df.columns[-1], 0)
    return df

def move_to_front_chum(df):
    cols = list(df)
    cols = [cols[-1]] + cols[:-1]
    return  df.loc[:, cols]

def move_to_front_chum2(df):
    cols = list(df)
    cols = [cols[-1]] + cols[:-1]
    return  df[cols]

def move_to_front_chum_inplace(df):
    cols = list(df)
    col = df[df.columns[-1]]
    df.drop(col.name, axis=1, inplace=True)
    df.insert(0, col.name, col)
    return df

def move_to_front_sachinmm(df):
    cols = list(df)
    cols = [cols[-1]] + cols[:-1]
    df = df.reindex(columns=cols, copy=False)
    return df

def move_to_front_citynorman_inplace(df):
    # This approach exploits that reset_index() moves the index
    # at the first position of the data frame.
    df.set_index(df.columns[-1], inplace=True)
    df.reset_index(inplace=True)
    return df

ret_mine = move_to_front_normanius_inplace(df.copy())
ret_chum = move_to_front_chum(df.copy())
ret_chum2 = move_to_front_chum_inplace(df.copy())
ret_sach = move_to_front_sachinmm(df.copy())
ret_city = move_to_front_citynorman_inplace(df.copy())

# Assert equivalence of solutions.
assert(ret_mine.equals(ret_chum))
assert(ret_mine.equals(ret_chum2))
assert(ret_mine.equals(ret_sach))
assert(ret_mine.equals(ret_city))

结果

# For n_cols = 11:
%timeit move_to_front_normanius_inplace(df)
# 963 µs ± 23.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit move_to_front_chum(df)
# 4.17 ms ± 118 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit move_to_front_chum_inplace(df)
# 11.4 ms ± 453 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit move_to_front_sachinmm(df)
# 3.83 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit move_to_front_citynorman_inplace(df)
# 1.66 ms ± 19 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

# For n_cols = 31:
%timeit move_to_front_normanius_inplace(df)
# 944 µs ± 20.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit move_to_front_chum(df)
# 10.7 ms ± 223 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit move_to_front_chum_inplace(df)
# 34.3 ms ± 530 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit move_to_front_sachinmm(df)
# 11.5 ms ± 273 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit move_to_front_citynorman_inplace(df)
# 1.68 ms ± 43.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

答案 6 :(得分:3)

df.set_index('Mid').reset_index()

似乎是一种非常简单的方法。

答案 7 :(得分:1)

要重新排列数据框的行,只需使用如下列表即可。

df = df[['Mid', 'Net', 'Upper', 'Lower', 'Zsore']]

这使得在以后阅读代码时所做的事情非常明显。还可以使用:

df.columns
Out[1]: Index(['Net', 'Upper', 'Lower', 'Mid', 'Zsore'], dtype='object')

然后剪切并粘贴以重新排序。

答案 8 :(得分:1)

这是一个非常简单的答案。

别忘了列名的两个(())'括号',否则会给你一个错误。


# here you can add below line and it should work 
df = df[list(('Mid','Upper', 'Lower', 'Net','Zsore'))]
df

                             Mid   Upper   Lower  Net  Zsore
Answer option                                                
More than once a day          2   0.22%  -0.12%   0%    65 
Once a day                    3   0.32%  -0.19%   0%    45
Several times a week          4   2.45%   1.10%   2%    78
Once a week                   6   1.63%  -0.40%   1%    65

答案 9 :(得分:0)

您可以尝试的最简单的方法是:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position 43: invalid start byte

答案 10 :(得分:0)

如果您想搬到另一个地方并重新分配名称,您可以执行以下操作:

df.insert(0, 'new col name', col)
df.pop("Mid")

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.insert.html