Применение преобразования и объединение нескольких столбцов из существующего кадра данных для формирования нового кадра данных в Pandas

1

Предположим, у меня есть dataframe, как показано ниже:

import pandas as pd

df1 = pd.DataFrame({
    'A' : ['foo ', 'b,ar', 'fo...o', 'bar', 'foo', 'bar', 'foo', 'foo'],
    'B' : ['one', 'one', 'two', 'three','two', 'two', 'one', 'three'],
})

Я хочу создать новый df2, df2, который представляет собой конкатенированную форму столбца "A" и "B" в df1 где каждая информация имеет верхний регистр. Это пример игрушки, и в моем случае я также могу иметь больше, чем столбец "А" и "В", поэтому я хотел бы сделать список столбцов переменной (то есть имена столбца могут варьироваться).

def tokenize(s):
    # replaces comma with space; removes non-alphanumeric chars; etc.
    return re.sub('[^0-9a-zA-Z\s]+', '', re.sub('[,]+', ' ', s)).lower().split()

df2 = pd.DataFrame() # create a new dataframe; not sure if I'm doing this right
cols_to_concat = ['A','B'] # there can be more than two columns in this list
for col in cols_to_concat:
    df2 = df1[col].apply(tokenize).apply(str.upper)
print(df2)
# here, I'd like the df2 to have just ONE column whose rows are 'FOOONE', 'BARONE', 'FOOTWO', 'BARTHREE','FOOTWO', 'BARTWO','FOOONE','FOOTHREE',...
Теги:
pandas
dataframe

2 ответа

1
Лучший ответ
ConcatCol = ['A', 'B']

df2 = pd.DataFrame(df1[ConcatCol].apply(lambda x: ''.join(x.str.upper()), axis=1), columns=['Col'])

На основе вашего комментария вы можете просто применить свою функцию после функции лямбда, если вы хотите объединить, а затем применить свою функцию:

# your function
def tokenize(s):
    # replaces comma with space; removes non-alphanumeric chars; etc.
    return re.sub('[^0-9a-zA-Z\s]+', '', re.sub('[,]+', ' ', s)).lower().split()

ConcatCol = ['A', 'B']

df2 = pd.DataFrame(df1[ConcatCol].apply(lambda x:  ''.join(x), axis=1).apply(tokenize), columns=['Col'])

       Col
0   [foo, one]
1   [b, arone]
2   [footwo]
3   [barthree]
4   [footwo]
5   [bartwo]
6   [fooone]
7   [foothree]

Чтобы применить вашу функцию сначала, а затем concat будет иметь немного другой ответ, потому что ваша функция использует split для создания списков. Итак, в конечном счете, вы просто собираетесь объединить список вместе, используя сумму:

def tokenize(s):
    # replaces comma with space; removes non-alphanumeric chars; etc.
    return re.sub('[^0-9a-zA-Z\s]+', '', re.sub('[,]+', ' ', s)).lower().split()

ConcatCol = ['A', 'B']

df2 = pd.DataFrame(df1[ConcatCol].apply(lambda x: (x.apply(tokenize))).sum(axis=1), columns=['Col'])

       Col
0   [foo, one]
1   [b, ar, one]
2   [foo, two]
3   [bar, three]
4   [foo, two]
5   [bar, two]
6   [foo, one]
7   [foo, three]
  • 0
    Спасибо за предложение. Но я пытаюсь создать новый фрейм данных, и имена столбцов («A», «B») должны приходить из списка, который может время от времени меняться. Учитывая это, как я могу достичь этого?
  • 0
    Еще раз спасибо Это очень близко к тому, что мне нужно. Просто быстрый вопрос (я упомянул об этом в качестве комментария в моем исходном вопросе, но он, вероятно, не был очевиден): что, если я хочу использовать пользовательскую функцию для манипулирования строкой (в отличие от простого использования str.upper() . Например, я обновил вопрос, включив в него метод с именем tokenize . Как я могу вызвать это в лямбда-вызове, чтобы повлиять на x ? Еще раз спасибо!
Показать ещё 4 комментария
2

Укороченная версия

list_o_cols = ['A', 'B']

df1[list_o_cols].sum(1).str.upper()

0      FOOONE
1      BARONE
2      FOOTWO
3    BARTHREE
4      FOOTWO
5      BARTWO
6      FOOONE
7    FOOTHREE
dtype: object

df2 = df1[list_o_cols].sum(1).str.upper().str.replace('O', '').to_frame('col_name')
df2

   col_name
0       FNE
1     BARNE
2       FTW
3  BARTHREE
4       FTW
5     BARTW
6       FNE
7    FTHREE
  • 0
    Спасибо за ответ. В случае, если это не было ясно в моем оригинальном сообщении, я отредактировал свой вопрос. Я хотел бы создать новый кадр данных, перебирая столбец за столбцом существующего кадра данных. Не могли бы вы еще раз взглянуть на мой вопрос и предложить еще несколько предложений? Спасибо.
  • 1
    Это то, что вы имели в виду?
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню