Подтвердить что ты не робот

Порядок столбцов в pandas.concat

Я делаю, как показано ниже:

data1 = pd.DataFrame({ 'b' : [1, 1, 1], 'a' : [2, 2, 2]})
data2 = pd.DataFrame({ 'b' : [1, 1, 1], 'a' : [2, 2, 2]})
frames = [data1, data2]
data = pd.concat(frames)
data


   a    b
0   2   1
1   2   1
2   2   1
0   2   1
1   2   1
2   2   1

Порядок столбцов данных находится в алфавитном порядке. Почему это так? и как сохранить первоначальный порядок?

4b9b3361

Ответ 1

Вы создаете DataFrames из словарей. Словари являются неупорядоченными, что означает, что у ключей нет определенного порядка. Так

d1 = {'key_a': 'val_a', 'key_b': 'val_b'}

и

d2 = {'key_b': 'val_b', 'key_a': 'val_a'}

совпадают.

В дополнение к этому я предполагаю, что pandas сортирует словарные ключи, по убыванию по умолчанию (к сожалению, я не нашел в документах никаких намеков, чтобы доказать это предположение), что привело к поведению, с которым вы столкнулись.

Таким образом, основная мотивация заключалась бы в том, чтобы использовать/изменить порядок столбцов в вашем DataFrame. Вы можете сделать это следующим образом:

import pandas as pd

data1 = pd.DataFrame({ 'b' : [1, 1, 1], 'a' : [2, 2, 2]})
data2 = pd.DataFrame({ 'b' : [1, 1, 1], 'a' : [2, 2, 2]})
frames = [data1, data2]
data = pd.concat(frames)

print(data)

cols = ['b' , 'a']
data = data[cols]

print(data)

Ответ 2

Вы можете создать исходные DataFrames с помощью OrderedDicts

from collections import OrderedDict

odict = OrderedDict()
odict['b'] = [1, 1, 1]
odict['a'] = [2, 2, 2]
data1 = pd.DataFrame(odict)
data2 = pd.DataFrame(odict)
frames = [data1, data2]
data = pd.concat(frames)
data


    b    a
0   1    2
1   1    2
2   1    2
0   1    2
1   1    2
2   1    2

Ответ 3

def concat_ordered_columns(frames):
    columns_ordered = []
    for frame in frames:
        columns_ordered.extend(x for x in frame.columns if x not in columns_ordered)
    final_df = pd.concat(frames)    
    return final_df[columns_ordered]       

# Usage
dfs = [df_a,df_b,df_c]
full_df = concat_ordered_columns(dfs)

Это должно работать.

Ответ 4

Вы также можете указать порядок следующим образом:

import pandas as pd

data1 = pd.DataFrame({ 'b' : [1, 1, 1], 'a' : [2, 2, 2]})
data2 = pd.DataFrame({ 'b' : [1, 1, 1], 'a' : [2, 2, 2]})
listdf = [data1, data2]
data = pd.concat(listdf)
sequence = ['b','a']
data = data.reindex(columns=sequence)

Ответ 5

Начиная с версии 0.23.0, вы можете запретить методу concat() сортировать возвращенный DataFrame. Например:

df1 = pd.DataFrame({ 'a' : [1, 1, 1], 'b' : [2, 2, 2]})
df2 = pd.DataFrame({ 'b' : [1, 1, 1], 'a' : [2, 2, 2]})
df = pd.concat([df1, df2], sort=False)

Будущая версия панд по умолчанию изменится на не сортируемую.

Ответ 6

Проще всего сначала сделать столбцы в том же порядке, а затем конкатить:

df2=df2[df1.columns]
df=pd.concat((df1,df2),axis=0)