Вставка нескольких столбцов в фрейм данных в определенном месте на основе другого фрейма данных - PullRequest
2 голосов
/ 27 сентября 2019

Я сталкиваюсь с этой проблемой, где у меня есть один фрейм данных, скажем, df1:

>>> df1 = pd.DataFrame(data = np.arange(45).reshape(-1,9), columns = ['A1','B1', 'C1', 
                                                       'A2', 'B2', 'C2','A3','B3','C3'])
>>> df1

   A1  B1  C1  A2  B2  C2  A3  B3  C3
0   0   1   2   3   4   5   6   7   8
1   9  10  11  12  13  14  15  16  17
2  18  19  20  21  22  23  24  25  26
3  27  28  29  30  31  32  33  34  35
4  36  37  38  39  40  41  42  43  44

И еще один фрейм данных df2:

>>> df2 = pd.DataFrame(data = np.arange(15).reshape(-1,3), columns = ['AB1','AB2','AB3'])
>>> df2

   AB1  AB2  AB3
0    0    1    2
1    3    4    5
2    6    7    8
3    9   10   11
4   12   13   14

Теперь я хочу, чтобы вставить столбцы df2 в df1 в определенных позициях, так что df1 становится (на самом деле новый df тоже будет работать):

>>> df1

   A1  AB1  B1  C1  A2  AB2  B2  C2  A3  AB3  B3  C3
0   0    0   1   2   3    1   4   5   6    2   7   8
1   9    3  10  11  12    4  13  14  15    5  16  17
2  18    6  19  20  21    7  22  23  24    8  25  26
3  27    9  28  29  30   10  31  32  33   11  34  35
4  36   12  37  38  39   13  40  41  42   14  43  44

Сейчас я достигаю этого, создав новый пустой df, затем перебираястолбцы обоих df, а затем последовательно добавляя каждый столбец.Что неэффективно, уродливо и наносит ущерб всей цели DataFrames.Итак, я хотел бы знать, есть ли уже метод для этого?Я не уверен, что на этот вопрос уже был дан ответ, но я уверен, что не нашел никаких результатов.Если это уже обсуждалось, я буду рад, если кто-нибудь укажет мне на это.

Ответы [ 2 ]

2 голосов
/ 27 сентября 2019

Вы можете использовать concat, а затем сортировать по , отсортированному по нескольким атрибутам и изменять порядок по новым значениям с подмножеством - []:

df = pd.concat([df1, df2], axis=1)
cols = sorted(df.columns, key = lambda x: (x[-1], x[:-1]))   
print (cols)
['A1', 'AB1', 'B1', 'C1', 'A2', 'AB2', 'B2', 'C2', 'A3', 'AB3', 'B3', 'C3']

df = df[cols]
print (df)
   A1  AB1  B1  C1  A2  AB2  B2  C2  A3  AB3  B3  C3
0   0    0   1   2   3    1   4   5   6    2   7   8
1   9    3  10  11  12    4  13  14  15    5  16  17
2  18    6  19  20  21    7  22  23  24    8  25  26
3  27    9  28  29  30   10  31  32  33   11  34  35
4  36   12  37  38  39   13  40  41  42   14  43  44

Другая идея заключается в создании MultiIndex in columns и сортировке по второму уровню, последним сглаживанием MultiIndex назад по map:

df1.columns = [df1.columns.str[:1], df1.columns.str[1]]
df2.columns = [df2.columns.str[:2], df2.columns.str[2]]

df = pd.concat([df1, df2],axis=1).sort_index(axis=1, level=1)
df.columns = df.columns.map(''.join)
print (df)
   A1  AB1  B1  C1  A2  AB2  B2  C2  A3  AB3  B3  C3
0   0    0   1   2   3    1   4   5   6    2   7   8
1   9    3  10  11  12    4  13  14  15    5  16  17
2  18    6  19  20  21    7  22  23  24    8  25  26
3  27    9  28  29  30   10  31  32  33   11  34  35
4  36   12  37  38  39   13  40  41  42   14  43  44 

РЕДАКТИРОВАТЬ:

Для более общего решения можно использовать DataFrame.reindex с MultiIndex.from_product:

df1 = pd.DataFrame(data = np.arange(45).reshape(-1,9), 
                   columns = ['A1','B1', 'C1', 'A2', 'B2', 'C2','A3','B3','C3'])
df2 = pd.DataFrame(data = np.arange(15).reshape(-1,3), columns = ['Sum1','Sum2','Sum3'])


#change order of values in MultiIndex
df1.columns = [df1.columns.str[1], df1.columns.str[:1]]
df2.columns = [df2.columns.str[3], df2.columns.str[:3]]

mux = pd.MultiIndex.from_product([['1','2','3'], ['A','Sum','B','C']])
print (mux)
MultiIndex([('1',   'A'),
            ('1', 'Sum'),
            ('1',   'B'),
            ('1',   'C'),
            ('2',   'A'),
            ('2', 'Sum'),
            ('2',   'B'),
            ('2',   'C'),
            ('3',   'A'),
            ('3', 'Sum'),
            ('3',   'B'),
            ('3',   'C')],
           )

df = pd.concat([df1, df2], axis=1).reindex(columns=mux)
df.columns = [f'{b}{a}' for a, b in df.columns]
print (df)
   A1  Sum1  B1  C1  A2  Sum2  B2  C2  A3  Sum3  B3  C3
0   0     0   1   2   3     1   4   5   6     2   7   8
1   9     3  10  11  12     4  13  14  15     5  16  17
2  18     6  19  20  21     7  22  23  24     8  25  26
3  27     9  28  29  30    10  31  32  33    11  34  35
4  36    12  37  38  39    13  40  41  42    14  43  44
0 голосов
/ 27 сентября 2019

На основании ответа @ jezrael я нашел другое решение:

cols = np.insert(df1.columns,range(1,len(df1.columns.values),3),df2.columns)
df = pd.concat([df1, df2], axis=1)
df[cols]

   A1  Sum1  B1  C1  A2  Sum2  B2  C2  A3  Sum3  B3  C3
0   0     0   1   2   3     1   4   5   6     2   7   8
1   9     3  10  11  12     4  13  14  15     5  16  17
2  18     6  19  20  21     7  22  23  24     8  25  26
3  27     9  28  29  30    10  31  32  33    11  34  35
4  36    12  37  38  39    13  40  41  42    14  43  44
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...