как вычесть значения столбцов строкового типа из другого столбца в пандах - PullRequest
0 голосов
/ 22 февраля 2019

У меня есть такой фрейм данных

df
col1         col2          col3
 A        black berry      black
 B        green apple      green
 C        red wine          red

Я хочу вычесть значения col3 из значений col2, результат будет выглядеть как

df1
col1        col2        col3
  A         berry       black
  B         apple       green
  C          wine        red

Как это сделать эффективноиспользуя панд

Ответы [ 4 ]

0 голосов
/ 22 февраля 2019

Нет необходимости for loop replace, обратите внимание, это заменить на row

df.col2=df.col2.replace(regex=r'(?i)'+ df.col3,value="")
df
Out[627]: 
  col1    col2   col3
0    A   berry  black
1    B   apple  green
2    C    wine    red

Подробнее

  col1   col2   col3
0    A  berry  black
1    B  apple  green
2    C   wine  apple# different row with row 2 , but same value 

df.col2.replace(regex=r'(?i)'+ df.col3,value="")
Out[629]: 
0    berry
1    apple# would not be replaced 
2     wine
0 голосов
/ 22 февраля 2019

Мы можем использовать метод применения:

def calculation(val):
    return val[0].replace(val[1],'').strip()

df['col4'] = df[['col2','col3']].apply(calculation, axis=1)

df:
  col1         col2   col3   col4
0    A  black berry  black  berry
1    B  green apple  green  apple
2    C    red wine     red   wine
0 голосов
/ 22 февраля 2019

Однолинейное решение:

df["col2"] = df.apply(lambda x: x["col2"].replace(x["col3"], "").strip(), axis=1)
0 голосов
/ 22 февраля 2019

Используйте list comprehension с replace и split:

df['col2'] = [a.replace(b, '').strip() for a, b in zip(df['col2'], df['col3'])]
print (df)
  col1   col2   col3
0    A  berry  black
1    B  apple  green
2    C   wine    red

Если порядок не важен, преобразуйте разделенные значения в наборы и вычтите:

df['col2'] = [' '.join(set(a.split())-set([b])) for a, b in zip(df['col2'], df['col3'])]
print (df)
  col1   col2   col3
0    A  berry  black
1    B  apple  green
2    C   wine    red

Или используйте генераторс условием if и join:

df['col2'] = [' '.join(c for c in a.split() if c != b) for a, b in zip(df['col2'], df['col3'])]

Производительность :

pic

Это былоустановка, использованная для генерации перфлот выше:

def calculation(val):
    return val[0].replace(val[1],'').strip()


def regex(df):
    df.col2=df.col2.replace(regex=r'(?i)'+ df.col3,value="")
    return df

def lambda_f(df):
    df["col2"] = df.apply(lambda x: x["col2"].replace(x["col3"], "").strip(), axis=1)
    return df

def apply(df):
    df['col2'] = df[['col2','col3']].apply(calculation, axis=1)
    return df

def list_comp1(df):
    df['col2'] = [a.replace(b, '').strip() for a, b in zip(df['col2'], df['col3'])]
    return df

def list_comp2(df):
    df['col2'] = [' '.join(set(a.split())-set([b])) for a, b in zip(df['col2'], df['col3'])]
    return df

def list_comp3(df):
    df['col2'] = [' '.join(c for c in a.split() if c != b) for a, b in zip(df['col2'], df['col3'])]
    return df


def make_df(n):
    d = {'col1': {0: 'A', 1: 'B', 2: 'C'}, 'col2': {0: 'black berry', 1: 'green apple', 2: 'red wine'}, 'col3': {0: 'black', 1: 'green', 2: 'red'}}
    df = pd.DataFrame(d)
    df = pd.concat([df] * n * 100, ignore_index=True)
    return df

perfplot.show(
    setup=make_df,
    kernels=[regex, lambda_f, apply, list_comp1,list_comp2,list_comp3],
    n_range=[2**k for k in range(2, 10)],
    logx=True,
    logy=True,
    equality_check=False,  # rows may appear in different order
    xlabel='len(df)')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...