Слияние значений в DataFrame

Есть дата фрейм:

df_o = pd.DataFrame([
    ['1', 'krt', '2', 'eb', '3', 'hbd', '4', 'sgj'],
    ['1', 'lkl', '2', 'wh', 'has', '3', 'a', '4', 'h'],
    ['1', 'f', 'qghn', '2', 'a', '3', 'lghm', '4', 'u']])

нужно его привести к виду:

df_o = pd.DataFrame([
    ['1', 'krt', '2', 'eb', '3', 'hbd', '4', 'sgj'],
    ['1', 'lkl', '2', 'wh/has', '3', 'a', '4', 'h'],
    ['1', 'f/qghn', '2', 'a', '3', 'lghm', '4', 'u']])

Нужно соседние текстовые значения объединить через символ /


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

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

Вообще, интересная задачка, жаль что вы не попробовали решить самостоятельно. Тут есть пара подводных камней: группировка по признаку .isalpha от itertools будет группировать как последовательные истинные вхождения, так и последовательные ложные. Кроме того, нужна реиндексация возвращаемого из хелпер-функции значения, для того, чтобы колонки могли быть встроены обратно в датафрейм с оригинальным индексом. Ну и помимо этого, пришлось повращать фрейм, чтобы нормально отработал метод explode и не пришлось менять ось приложения лямбды.
В общем:

import itertools
import pandas as pd

df = pd.DataFrame([
    ['1', 'krt', '2', 'eb', '3', 'hbd', '4', 'sgj'],
    ['1', 'lkl', '2', 'wh', 'has', '3', 'a', '4', 'h'],
    ['1', 'f', 'qghn', '2', 'a', '3', 'lghm', '4', 'u']])

def concat_alpha(s):
    ret_val = ["/".join([e for e in g[1]]) if g[0] else [e for e in g[1]]
               for g in itertools.groupby(s, key=lambda x:x.isalpha())]
    return pd.Series(ret_val).explode().reset_index(drop=True)

res = df.T.apply(lambda x: concat_alpha(x.dropna())).T

res:

   0       1  2       3  4     5  6    7
0  1     krt  2      eb  3   hbd  4  sgj
1  1     lkl  2  wh/has  3     a  4    h
2  1  f/qghn  2       a  3  lghm  4    u
→ Ссылка
Автор решения: Алексей Р

Простой вариант. Обрабатываем каждую строку и склеиваем обратно.

def glue(s):
    lst = s.tolist()
    out, buf = [], lst.pop(0)

    while lst:
        x = lst.pop(0)
        if not buf is None and not x is None and not x.isdigit() and not buf.isdigit():
            buf += '/' + x
        else:
            out.append(buf)
            buf = x
    if not buf is None:
        out.append(buf)
    return pd.Series(out)


df_o = pd.DataFrame([
    ['1', 'krt', '2', 'eb', '3', 'hbd', '4', 'sgj'],
    ['1', 'lkl', '2', 'wh', 'has', '3', 'a', '4', 'h'],
    ['1', 'f', 'qghn', '2', 'a', '3', 'lghm', '4', 'u']])

df = df_o.apply(glue, axis=1)
print(df)
   0       1  2       3  4     5  6    7
0  1     krt  2      eb  3   hbd  4  sgj
1  1     lkl  2  wh/has  3     a  4    h
2  1  f/qghn  2       a  3  lghm  4    u
→ Ссылка