Как динамически объединять несколько столбцов, где имена столбцов хранятся в виде строки с разделителями Pandas

Я пытаюсь объединить столбцы динамически. Имена столбцов хранятся в виде строк с разделителями в столбце «слияние»:

 import pandas as pd

 df = pd.DataFrame({'prodName': ['p1', 'p2', 'p3'],
               'mfr': ['m1', 'm2', 'm3'],
               'segment': ['s1','s2','s3'],
       'brand': ['b1','b2','b3'],
       'merge': ['mfr!segment','mfr!brand','segment!brand']})
 df

df вывод:

     prodName   mfr  segment   brand           merge
 0        p1     m1       s1      b1     mfr!segment  
 1        p2     m2       s2      b2       mfr!brand
 2        p3     m3       s3      b3   segment!brand

df ожидаемый результат:

     prodName   mfr  segment   brand           merge   new_col
 0        p1     m1       s1      b1     mfr!segment      m1_s1    
 1        p2     m2       s2      b2       mfr!brand      m2_b2
 2        p3     m3       s3      b3   segment!brand      s3_b3

Я пытался использовать pd.factorise, но он ожидает данные 1D. Я добился желаемого результата, перебирая строки

 for index, row in df:
     colstomerge=[col for col in row["merge"].lower().split("!")]
     df['new_col']=df.loc[:,colstomerge].astype(str).sum(axis=1)

Я ищу более элегантное и оптимальное решение, спасибо.

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

Ответы 2

Вы можете использовать apply() и определить функцию, которая выполняет конкатенацию в зависимости от столбца merge:

import pandas as pd

# Define function to merge strings depending on merge col
def merger(x):
    a, b = x['merge'].split('!')
    return x[a] + "_" + x[b]

df = pd.DataFrame({'prodName': ['p1', 'p2', 'p3'],
              'mfr': ['m1', 'm2', 'm3'],
              'segment': ['s1','s2','s3'],
      'brand': ['b1','b2','b3'],
      'merge': ['mfr!segment','mfr!brand','segment!brand']})

# Apply function to rows
df['new_col'] = df.apply(merger, axis=1)

df вывод:

  prodName mfr segment brand          merge new_col
0       p1  m1      s1    b1    mfr!segment   m1_s1
1       p2  m2      s2    b2      mfr!brand   m2_b2
2       p3  m3      s3    b3  segment!brand   s3_b3

спасибо за ваш ответ, мне действительно нужно объединить более 2 столбцов в моем реальном наборе данных

Noman Ahmed 14.04.2023 08:01
Ответ принят как подходящий

Вы можете сделать следующее - назначить временный столбец со списком столбцов, которые нужно объединить, и объединить с помощью .join. Он должен работать для любого количества столбцов, разделенных '!' в столбце "объединить"

df["new_col"] = df.assign(cols=df["merge"].str.split("\!")).apply(
    lambda row: "_".join(row[row["cols"]].fillna("")), axis=1
)

print(df)

df вывод:

  prodName mfr segment brand          merge new_col
0       p1  m1      s1    b1    mfr!segment   m1_s1
1       p2  m2      s2    b2      mfr!brand   m2_b2
2       p3  m3      s3    b3  segment!brand   s3_b3

Спасибо, у меня все еще есть проблемы с нанами, например, представьте, если «mfr» - это нан для одного из строк

Noman Ahmed 14.04.2023 08:00

Вы можете сделать fillna("") в лямбде, как отредактировано в ответе, тогда np.nan будет отображаться как пустой, например. _b2 если m2 был np.nan, если вам нужна какая-то другая строка, такая как «nan», просто введите fillna («nan»)

SomeDude 14.04.2023 14:15

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

Похожие вопросы