Python классифицирует столбцы Dataframe на основе части имени столбца

Воспроизводимые данные:

import random
    data = {'test_1_a':random.sample(range(1, 50), 7),
            'test_1_b':random.sample(range(1, 50), 7),
    'test_1_c':random.sample(range(1, 50), 7),
    'test_2_a':random.sample(range(1, 50), 7),
    'test_2_b':random.sample(range(1, 50), 7),
    'test_2_c':random.sample(range(1, 50), 7),
    'test_3_a':random.sample(range(1, 50), 7),
    'test_4_b':random.sample(range(1, 50), 7),
    'test_4_c':random.sample(range(1, 50), 7)}
    df = pd.DataFrame(data)

Описание:

У меня есть фрейм данных, аналогичный приведенному выше примеру с 1000 столбцами. Формат имени столбца следующий:

test_количество_семья, поэтому test_1_c будет числовым типом 1 и семейством "c"

Я хочу классифицировать df по именам столбцов того же типа «семейство». Итак, мой окончательный вывод должен быть списком списков одинаковых семейных значений:

Пример вывода:

[ [значения a_family], [значения b_family],...]

это также будет выглядеть как значения столбцов:

[[тест_1_а, тест_2_а, тест_3_а], [тест_1_б, тест_2_б, тест_3_б], ...]

Что я имею:

#### transfers data frame into a sorted dict (by column name) by columns as key
col_names = [ i for (i,j) in df.iteritems() ]
col_vals = [ j for (i,j) in df.iteritems() ]

df_dict = dict(zip(col_names, col_vals))


families = np.unique([ i.split("_")[2] for i in dict1.keys() ])

Я классифицировал каждое имя столбца с его связанным значением и извлек уникальное количество групп, которые я хочу иметь в конечном выводе как «семейства». Теперь я ищу помощь в категоризации фрейма данных по длине (семействам) количества списков, идентичных выходному примеру, который я привел выше.

Я надеюсь, что мое объяснение было ясным, спасибо за ваше время!

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
0
33
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Давайте проследим за различными семействами в словаре, где ключи — это буквы (семейства), а значения — списки, содержащие столбцы из определенного семейства.

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

from collections import defaultdict
families = defaultdict(list)

for col in df.columns:
    families[col[-1]].append(df[col])

Теперь, например, в families["a"] у нас есть:

[0    26
 1    13
 2    11
 3    35
 4    43
 5    45
 6    46
 Name: test_1_a, dtype: int64,
 0    10
 1    15
 2    20
 3    43
 4    40
 5    35
 6    22
 Name: test_2_a, dtype: int64,
 0    35
 1    48
 2    38
 3    13
 4     3
 5    10
 6    25
 Name: test_3_a, dtype: int64]

Мы можем легко получить фрейм данных для каждой семьи с помощью concat.

df_a = pd.concat(families["a"], axis=1)

Получает нас:

   test_1_a  test_2_a  test_3_a
0        26        10        35
1        13        15        48
2        11        20        38
3        35        43        13
4        43        40         3
5        45        35        10
6        46        22        25

Если бы мы создали словарь фреймов данных для каждого семейства,

dfs = {f"df_{fam}" : pd.concat(families[fam], axis=1) for fam in families.keys()}

Теперь словарь dfs содержит:

{'df_a':    test_1_a  test_2_a  test_3_a
 0        26        10        35
 1        13        15        48
 2        11        20        38
 3        35        43        13
 4        43        40         3
 5        45        35        10
 6        46        22        25,
 'df_b':    test_1_b  test_2_b  test_4_b
 0        18         4        44
 1        48        43         2
 2        30        21         4
 3        46        12        16
 4        42        14        25
 5        22        24        13
 6        43        40        43,
 'df_c':    test_1_c  test_2_c  test_4_c
 0        25        15         5
 1        36        39        28
 2         6         3        37
 3        22        48        16
 4         2        34        25
 5        39        16        30
 6        32        36         2}

Что вы думаете о таком подходе? Используйте pd.wide_to_long с результатом длинного фрейма данных с разделенными столбцами, один со всем classification, например 1_a, один только с числом, один с семейством и их значениями.

df = (pd.wide_to_long(
    df.reset_index(),stubnames='test_',i='index',j='classification',suffix='\d_\w')
      .reset_index()
      .drop('index',axis=1)
      .rename(columns={'test_':'values'}))

df[['number', 'family']] = df['classification'].str.split('_', expand=True)
df = df.reindex(columns=['classification', 'number', 'family', 'values'])

print(df)

   classification number family  values
0             1_a      1      a      29
1             1_a      1      a      46
2             1_a      1      a       2
3             1_a      1      a       6
4             1_a      1      a      16
..            ...    ...    ...     ...
58            4_c      4      c      30
59            4_c      4      c      23
60            4_c      4      c      26
61            4_c      4      c      40
62            4_c      4      c      39

Легко группировать или фильтровать для большего анализа. Если вы хотите получить dicts или lists конкретных данных, вот несколько примеров:

filter1 = df.loc[df['classification']=='1_a',:]
filter2 = df.loc[df['number']=='2','values']

filter1.to_dict(orient='list')
Output: 
{'classification': ['1_a', '1_a', '1_a', '1_a', '1_a', '1_a', '1_a'],
 'number': ['1', '1', '1', '1', '1', '1', '1'],
 'family': ['a', 'a', 'a', 'a', 'a', 'a', 'a'],
 'values': [29, 46, 2, 6, 16, 12, 38]}

filter2.tolist()
Output: 
[8, 2, 43, 9, 5, 30, 28, 26, 25, 49, 3, 1, 47, 44, 16, 9, 8, 15, 24, 36, 1]

Не уверен, что полностью понимаю вопрос; это то, что вы имеете в виду:

dict(list(df.groupby(df.columns.str[-1], axis = 1)))

{'a':    test_1_a  test_2_a  test_3_a
 0        20        36        14
 1         4         7        16
 2        28        13        28
 3         3        40         9
 4        38        41         5
 5        34        47        18
 6        49        25        46,
 'b':    test_1_b  test_2_b  test_4_b
 0        35        10        44
 1        46        14        23
 2        26        11        36
 3        17        27         4
 4        13        16        42
 5        20        38         9
 6        41        22        18,
 'c':    test_1_c  test_2_c  test_4_c
 0        22         2        26
 1        42        24         3
 2        15        16        41
 3         7        11        16
 4        40        37        47
 5        38         7        33
 6        39        22        24}

Это группирует столбцы по последней букве в имени столбца.

Если это не то, что вы имеете в виду, пожалуйста, прокомментируйте и, возможно, объясните немного лучше, где я неправильно понял ваше намерение.

Привет, да, это именно то, что я хочу

Ilayda Göden 17.05.2022 16:18

Другие вопросы по теме