Как вычесть значения столбцов строкового типа из другого столбца в пандах
У меня есть фрейм данных, как это
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 ответа
Решение
Использование 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'])]
Производительность:
https://s tackr u.com/images/e28b56236cb88a113a87688463bcaaa160252d40.png
Эта настройка использовалась для генерации перфлота выше:
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)')
Однолинейное решение:
df["col2"] = df.apply(lambda x: x["col2"].replace(x["col3"], "").strip(), axis=1)
Мы можем использовать метод apply:
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
Незачем 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