Основываясь на условии, как заполнить столбцы именами столбцов, строка которых не равна нулю

Здравствуйте, моя проблема почти такая же, как в этом посте: Как заполнить столбец именами столбцов, строки которых не равны NULL в Pandas?

Но в моем случае вместо конкатенации мне нужно заполнить столбец в зависимости от того, является ли имя столбца страной или сегментом.

Обновлено: стол У меня изначально так:

Сегмент Страна Сегмент 1 Страна 1 Сегмент 2 Нэн Нэн 123456 123456 Нэн Нэн Нэн Нэн Нэн Нэн Нэн Нэн Нэн 123456 123456 Нэн Нэн Нэн 123456 123456

На самом деле у меня есть это (первые столбцы заполняются двумя строками перед последней в моем коде:

Сегмент Страна Сегмент 1 Страна 1 Сегмент 2 Сегмент1 ; Страна1 ; Сегмент1 ; Страна1 ; 123456 123456 Нэн Нэн Нэн Нэн Нэн Нэн страна1 ; сегмент2 ; страна1 ; сегмент2 ; Нэн 123456 123456 страна1 ; сегмент2 ; страна1 ; сегмент2 ; Нэн 123456 123456

А мне нужно это:

Сегмент Страна Сегмент 1 Страна 1 Сегмент 2 Сегмент 1 Страна1 123456 123456 Нэн Нэн Нэн Нэн Нэн Нэн Сегмент 2 страна1 Нэн 123456 123456 Сегмент 2 страна1 Нэн 123456 123456

Обновлено: мой код на самом деле выглядит так после попытки интегрировать anwser: Ошибка: AttributeError: Can only use .str accessor with string values!. Did you mean: 'std'?

#For each column in df, check if there is a value and if yes : first copy the value into the 'Amount' Column, then copy the column name into the 'Segment' or 'Country' columns
for column in df.columns[3:]:
    valueList = df[column][3:].values
    valueList = valueList[~pd.isna(valueList)]
    def detect(d):
        cols = d.columns.values
        dd = pd.DataFrame(columns=cols, index=d.index.unique())
        for col in cols:
            s = d[col].loc[d[col].str.contains(col[0:3], case=False)].str.replace(r'(\w+)(\d+)', col + r'\2')
            dd[col] = s
        return dd

    #Fill amount Column with other columns values if NaN
    if column in isSP:
        df['Amount'].fillna(df[column], inplace = True)
        df['Segment'] = df.iloc[:, 3:].notna().dot(df.columns[3:] + ';' ).str.strip(';')
        df['Country'] = df.iloc[:, 3:].notna().dot(df.columns[3:] + ' ; ' ).str.strip(';')
        df[['Segment', 'Country']] = detect(df[['Segment', 'Country']].apply(lambda x: x.astype(str).str.split(r'\s+[+]\s+').explode()))

Большое спасибо.

Как определить, является ли данная строка сегментом или страной?

Azhar Khan 16.11.2022 16:01

Чтобы определить, является ли заголовок сегментом, я использую эту строку: isSP = [col for col in df.columns if "_sp" in col] А для страны все остальное, но в идеале я хотел бы использовать список Country.csv (Список находится в папке проекта).

Gatarlo 16.11.2022 16:15

Все сегменты имеют «_sp» в своем имени.

Gatarlo 16.11.2022 16:21
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
85
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Данный:

         Segment        Country  Segment 1  Country 1  Segment 2
0  Seg1;Country1  Seg1;Country1    123456    123456       Nan
1            Nan            Nan       Nan       Nan       Nan
2  country1;seg2  country1;seg2       Nan    123456    123456
3  country1;seg2  country1;seg2       Nan    123456    123456

Делает

cols = ['Segment', 'Country']
df[cols] = df.Segment.str.split(';', expand=True)

is_segment = 'eg' # ~You'll used '_sp' here~

# Let's sort values with a custom key, namely,
# does the string (not) contain what we're looking for?
key = lambda x: ~x.str.contains(is_segment, na=False)
func = lambda x: x.sort_values(key=key, ignore_index=True)
df[cols] = df[cols].apply(func, axis=1)

print(df)

Вывод:

  Segment   Country Segment 1 Country 1 Segment 2
0    Seg1  Country1    123456    123456       Nan
1     Nan      None       Nan       Nan       Nan
2    seg2  country1       Nan    123456    123456
3    seg2  country1       Nan    123456    123456

Версия с интенсивным выражением:

pattern = '(?P<Segment>.+eg\d);(?P<Country>.+)|(?P<Country_>.+);(?P<Segment_>.+eg\d)'
extract = df.Segment.str.extract(pattern)
for col in cols:
    df[col] = extract.filter(like=col).bfill(axis=1)[col]

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