Сохраните первый экземпляр столбца и удалите остальные, используя частичный текст в имени столбца

В df есть столбец ABC_81, ABC_y, ABC_aa, ZXC_aa, ZXC_5, ZXC_hi:

data = {
    'ABC_81': [1, 2, 3],
    'ABC_y': [4, 5, 6],
    'ABC_aa': [7, 8, 9],
    'ZXC_aa': [10, 11, 12],
    'ZXC_5': [13, 14, 15],
    'ZXC_hi': [16, 17, 18],
    'PPP_tr' : [88,55,99],
    'QWE_gf' : [78,98,14]
    }

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

Keep ABC_81,
Drop ABC_y, ABC_aa

Сходным образом

Keep ZXC_aa,
Drop ZXC_5, ZXC_hi

и так далее

Результат должен быть:

data = {
    'ABC_81': [1, 2, 3],
    'ZXC_aa': [10, 11, 12],
    'PPP_tr' : [88,55,99],
    'QWE_gf' : [78,98,14]
    }

Кроме того, можно ли это сделать, не зная имен столбцов?

2
0
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Да, вы можете добиться этого, не зная явно имена столбцов, используя pandas. Например, ты можешь сделать это, братан:

import pandas as pd


data = {
    'ABC_81': [1, 2, 3],
    'ABC_y': [4, 5, 6],
    'ABC_aa': [7, 8, 9],
    'ZXC_aa': [10, 11, 12],
    'ZXC_5': [13, 14, 15],
    'ZXC_hi': [16, 17, 18]
}

df = pd.DataFrame(data)

# Create a list to store the columns to keep
columns_to_keep = []

# Iterate over the columns of the DataFrame
for col in df.columns:
    # Check if the column starts with 'ABC' or 'ZXC'
    if col.startswith('ABC') or col.startswith('ZXC'):
        # Append the first occurrence of the column name to the list
        if col[:3] not in columns_to_keep:
            columns_to_keep.append(col[:3])

# Filter the DataFrame to keep only the columns in columns_to_keep
df_filtered = df[[col for col in df.columns if col[:3] in columns_to_keep]]

print(df_filtered)

Этот код перебирает столбцы DataFrame и проверяет, начинается ли каждый столбец с «ABC» или «ZXC». Затем он добавляет первые три символа имени столбца в список columns_to_keep, если это первое вхождение. Наконец, он фильтрует DataFrame, чтобы сохранить только столбцы, присутствующие в columns_to_keep. (надеюсь, я хорошо понимаю)

Для моих исходных данных (как вы отвечаете) ваш код не работает. Я обновил данные, включив в них некоторые столбцы, которые не следует удалять: «PPP_tr» и «QWE_gf».

Dan 14.04.2024 20:46
Ответ принят как подходящий

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

m = ~df.columns.str.extract(r'^([^_]+)', expand=False).duplicated()

out = df.loc[:, m]

В качестве однострочника:

out = df.loc[:, ~df.columns.str.extract(r'^([^_]+)', expand=False).duplicated()]

Выход:

   ABC_81  ZXC_aa  PPP_tr  QWE_gf
0       1      10      88      78
1       2      11      55      98
2       3      12      99      14

Промежуточные продукты:

df.columns.str.extract(r'^([^_]+)', expand=False)
# Index(['ABC', 'ABC', 'ABC', 'ZXC', 'ZXC', 'ZXC'], dtype='object')

df.columns.str.extract(r'^([^_]+)', expand=False).duplicated()
# array([False,  True,  True, False,  True,  True, False, False])

~df.columns.str.extract(r'^([^_]+)', expand=False).duplicated()
# array([ True, False, False,  True, False, False,  True,  True])

демо регулярного выражения

более сложный фильтр

При необходимости вы можете добавить дополнительные условия:

# extract prefix
prefix = df.columns.str.extract(r'^([^_]+)', expand=False)
# identify duplicated columns that match ABC/ZXC
m = prefix.isin(['ABC', 'ZXC']) & prefix.duplicated()

# select all but duplicated ABC/ZXC
out = df.loc[:, ~m]

Ваше решение работает. Идя дальше, допустим, у нас также есть PPP_tr и PPP_aa, которые нельзя удалять? следует отбросить только ABC и ZXC.

Dan 14.04.2024 21:00

Вы можете добавить второе условие. Посмотреть обновление

mozway 14.04.2024 21:39

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