Разделение таблиц на части по столбцам в цикле

Eсть ряд таблиц с данными. Для каждой таблицы мне необходимо провести разделение на две таблицы в зависимости от названия столбцов. На данный момент я сделал следующие шаги:

  1. Создал контнейнер из существующих таблиц list_m, которые нужно разделить
list_m = [other_inc_cons_cumsum_m, pr_cons_cumsum_m, ndfl_cons_cumsum_m, excise_cons_cumsum_m, property_cons_cumsum_m, ndpi_cumsum_m]  
  1. Создал два контейнера из пустых фреймов данных, в которые собираюсь записать разделенные столбцы
list_m_rel = [other_inc_cons_cumsum_m_rel, pr_cons_cumsum_m_rel, ndfl_cons_cumsum_m_rel, excise_cons_cumsum_m_rel, property_cons_cumsum_m_rel, ndpi_cumsum_m_rel]  
  
list_m_diff = [other_inc_cons_cumsum_m_diff, pr_cons_cumsum_m_diff, ndfl_cons_cumsum_m_diff, excise_cons_cumsum_m_diff, property_cons_cumsum_m_diff, ndpi_cumsum_m_diff]   
  1. Далее, если в названии столбца таблицы из list_m есть _rel, то этот столбец идет в таблицу из контейнера list_m_rel.
    for table_t, table_rel in zip(set_m, set_m_rel):
       l = [column for column in table_t.columns if re.findall('_rel', column) == ['_rel']]
       table_rel = table_t[l].copy()
       table_t.drop(columns = l, inplace = True) 
  1. Далее если в названии столбца таблицы из list_m есть _diff, то этот столбец идет в таблицу из контейнера list_m_diff.

    for table_t, table_diff in zip(set_m, set_m_diff):
      l = [column for column in table_t.columns if re.findall('_diff', column) == ['_diff']]
      table_diff = table_t[l]
      table_t.drop(columns = l, inplace = True)

Проблема заключается в том, что по итогу таблицы из list_m лишаются столбцов с _diff и _rel, а таблицы из list_m_diff и list_m_rel остаются пустыми.


Ответы (3 шт):

Автор решения: strawdog

я бы предложил сделать так:

исходные данные:

import pandas as pd

# исходные фреймы
df1 = pd.DataFrame({"abcd":[1,2,3], "fgkl":[11,12,13]})
df2 = pd.DataFrame({"cd_ab":[21,22,23], "5_kl":[41,42,43]})

# результирующие фреймы:

ab = pd.DataFrame()
kl = pd.DataFrame()

и само решение:

for df in [df1, df2]: # берем каждый датафрейм из списка
    for x in list(df.columns): # берем название каждого столбца датафрейма
        if "ab" in x:
            ab = pd.concat([ab, df[x]], axis=1)
        if "kl" in x:
            kl = pd.concat([kl, df[x]], axis=1)

тогда и исходные фреймы остаются в целости и результирующие получают то, что вам нужно:

#ab:
   abcd  cd_ab
0     1     21
1     2     22
2     3     23
       
#kl:
   fgkl  5_kl
0    11    41
1    12    42
2    13    43
→ Ссылка
Автор решения: MaxU

Из комментариев:

Но мне необходимо, чтобы таблица df1 распалась на две отдельные таблицы, а таблица df2 распалась на две другие таблицы

Не уверен, что вы действительно хотите множить в памяти одни и те же данные в различном виде. Зачем разделять и сохранять каждый фрейм на два если это легко делается "на лету":

Пример:

a = pd.DataFrame({"a_rel":[1,2,3], "a_diff":[11,12,13]})
b = pd.DataFrame({"b_rel":[21,22,23], "b_diff":[41,42,43]})
c = pd.DataFrame({"c_rel":[31,32,33], "c_diff":[51,52,53]})

если нам нужны все "_rel" столбцы:

In [16]: pd.concat([a,b,c], axis=1).filter(regex="_rel$")
Out[16]: 
   a_rel  b_rel  c_rel
0      1     21     31
1      2     22     32
2      3     23     33

In [17]: pd.concat([a,b,c], axis=1).filter(regex="_diff$")
Out[17]: 
   a_diff  b_diff  c_diff
0      11      41      51
1      12      42      52
2      13      43      53

разумеется тоже самое можно делать с каждым отдельным фреймом:

In [18]: a.filter(regex="_rel$")
Out[18]: 
   a_rel
0      1
1      2
2      3
→ Ссылка
Автор решения: Александр Гордеев

Есть такая реализация:

set_m = [other_inc_cons_cumsum_m, pr_cons_cumsum_m, ndfl_cons_cumsum_m, excise_cons_cumsum_m, property_cons_cumsum_m, ndpi_cons_cumsum_m]

for table in set_m:
  for column in table.columns:
    table[column + ' _rel'] = (table[column] - table[column].shift(12)) / table[column].shift(12)
    table[column + ' _diff'] = (table[column]) - table[column].shift(12)

map_rel = {}
map_diff = {}
names = ["other_inc_cons", "pr_cons", "ndfl_cons", "excise_cons", "property_cons", "ndpi_cons"]

for table_t, name in zip(set_m, names):
  l = [column for column in table_t.columns if re.findall('_rel', column) == ['_rel']]
  map_rel[name+'_cumsum_m_rel'] = table_t[l]
  table_t.drop(columns = l, inplace = True)

for table_t, name in zip(set_m, names):
  l = [column for column in table_t.columns if re.findall('_diff', column) == ['_diff']]
  map_diff[name+'_cumsum_m_diff'] = table_t[l]
  table_t.drop(columns = l, inplace = True)

Потом каждая таблица из map-ов выгружается в эксель.

→ Ссылка