-->

move column in pandas dataframe

2020-02-19 07:54发布

问题:

I have the following dataframe:

   a  b   x  y
0  1  2   3 -1
1  2  4   6 -2
2  3  6   9 -3
3  4  8  12 -4

How can I move columns b and x such that they are the last 2 columns in the dataframe? I would like to specify b and x by name, but not the other columns.

回答1:

You can rearrange columns directly by specifying their order:

df = df[['a', 'y', 'b', 'x']]

In the case of larger dataframes where the column titles are dynamic, you can use a list comprehension to select every column not in your target set and then append the target set to the end.

>>> df[[c for c in df if c not in ['b', 'x']] 
       + ['b', 'x']]
   a  y  b   x
0  1 -1  2   3
1  2 -2  4   6
2  3 -3  6   9
3  4 -4  8  12

To make it more bullet proof, you can ensure that your target columns are indeed in the dataframe:

cols_at_end = ['b', 'x']
df = df[[c for c in df if c not in cols_at_end] 
        + [c for c in cols_at_end if c in df]]


回答2:

cols = list(df.columns.values) #Make a list of all of the columns in the df
cols.pop(cols.index('b')) #Remove b from list
cols.pop(cols.index('x')) #Remove x from list
df = df[cols+['b','x']] #Create new dataframe with columns in the order you want


回答3:

You can use to way below. It's very simple, but similar to the good answer given by Charlie Haley.

df1 = df.pop('b') # remove column b and store it in df1
df2 = df.pop('x') # remove column x and store it in df2
df['b']=df1 # add b series as a 'new' column.
df['x']=df2 # add b series as a 'new' column.

Now you have your dataframe with the columns 'b' and 'x' in the end. You can see this video from OSPY : https://youtu.be/RlbO27N3Xg4



回答4:

You can use pd.Index.difference with np.hstack, then reindex or use label-based indexing. In general, it's a good idea to avoid list comprehensions or other explicit loops with NumPy / Pandas objects.

cols_to_move = ['b', 'x']
new_cols = np.hstack((df.columns.difference(cols_to_move), cols_to_move))

# OPTION 1: reindex
df = df.reindex(columns=new_cols)

# OPTION 2: direct label-based indexing
df = df[new_cols]

# OPTION 3: loc label-based indexing
df = df.loc[:, new_cols]

print(df)

#    a  y  b   x
# 0  1 -1  2   3
# 1  2 -2  4   6
# 2  3 -3  6   9
# 3  4 -4  8  12


回答5:

This function will reorder your columns without losing data. Any omitted columns remain in the center of the data set:

def reorder_columns(columns, first_cols=[], last_cols=[], drop_cols=[]):
    columns = list(set(columns) - set(first_cols))
    columns = list(set(columns) - set(drop_cols))
    columns = list(set(columns) - set(last_cols))
    new_order = first_cols + columns + last_cols
    return new_order

Example usage:

my_list = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth']
reorder_columns(my_list, first_cols=['fourth', 'third'], last_cols=['second'], drop_cols=['fifth'])

# Output:
['fourth', 'third', 'first', 'sixth', 'second']

To assign to your dataframe, use:

my_list = df.columns.tolist()
reordered_cols = reorder_columns(my_list, first_cols=['fourth', 'third'], last_cols=['second'], drop_cols=['fifth'])
df = df[reordered_cols]


回答6:

An alternative, more generic method;

from pandas import DataFrame


def move_columns(df: DataFrame, cols_to_move: list, new_index: int) -> DataFrame:
    """
    This method re-arranges the columns in a dataframe to place the desired columns at the desired index.
    ex Usage: df = move_columns(df, ['Rev'], 2)   
    :param df:
    :param cols_to_move: The names of the columns to move. They must be a list
    :param new_index: The 0-based location to place the columns.
    :return: Return a dataframe with the columns re-arranged
    """
    other = [c for c in df if c not in cols_to_move]
    start = other[0:new_index]
    end = other[new_index:]
    return df[start + cols_to_move + end]


回答7:

You can also do this as a one-liner:

df.drop(columns=['b', 'x']).assign(b=df['b'], x=df['x'])