Заменить значение столбца, содержащего выражение, результатом этого выражения

Есть столбцы в которых содержатся значения следующего типа "85+2".
Хотелось бы заменить такое значение следующим - "87".

Выполняю следущий код:

import pandas
import seaborn as sns

data = pandas.read_csv('players_20.csv')
data['value_eur'] /= 1000000

def best_pos(df):
  idx = [' ls', ' st', ' rs', ' lw', ' lf', ' cf', ' rf', ' rw', ' lam', ' cam', ' ram', ' lm', ' lcm', ' cm', ' rcm', ' rm', ' lwb', ' ldm', ' cdm', ' rdm', ' rwb', ' lb', ' lcb', ' cb', ' rcb', ' rb']
  tot = []
  for i in idx:
    hemi = df[i].split('+')
    total = int(hemi[0])+int(hemi[2])
    tot.append(total)
    return tot

data.apply(best_pos)

Происходит ошибка компиляции, не понимаю в чем проблема.

Исходный датасет.


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

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

Если у вас "происходит ошибка", то нужно приводить ее текст в вопросе.

Если вам нужно просто сложить числа в колонках, то попробуйте сделать так (обратите внимание на список с названиями колонок - в них НЕТ пробела:

cols = idx = ['ls', 'st', 'rs', 'lw', 'lf', 'cf', 'rf', 'rw', 'lam', 'cam', 'ram', 'lm', 'lcm', 'cm', 'rcm', 'rm', 'lwb', 'ldm', 'cdm', 'rdm', 'rwb', 'lb', 'lcb', 'cb', 'rcb', 'rb']
for i in cols:
    df[i].fillna(0, inplace=True)
    df[i] = df[i].apply(lambda x: eval(str(x)))
→ Ссылка
Автор решения: MaxU

Если суть вопроса в том как вычислить арифметическое выражение в столбцах, то это можно сделать так:

df = pd.read_csv(r"D:\download\players_20.csv")

col_idx = (df.columns == "ls").argmax()

r = (df
     .iloc[:, col_idx:]
     .dropna()
     .apply(lambda x: x.str.split("+", expand=True)
                       .rename(columns={0:"a", 1:"b"})
                       .astype(int).eval("a+b")))

результат:

In [44]: r
Out[44]:
       ls  st  rs  lw  lf  ...  lb  lcb  cb  rcb  rb
0      91  91  91  95  95  ...  65   54  54   54  65
1      94  94  94  92  93  ...  64   56  56   56  64
2      87  87  87  93  92  ...  64   49  49   49  64
4      86  86  86  92  91  ...  64   52  52   52  64
5      85  85  85  90  90  ...  76   69  69   69  76
...    ..  ..  ..  ..  ..  ...  ..  ...  ..  ...  ..
18273  34  34  34  33  33  ...  47   48  48   48  47
18274  35  35  35  35  34  ...  48   49  49   49  48
18275  45  45  45  45  45  ...  49   51  51   51  49
18276  45  45  45  47  46  ...  50   51  51   51  50
18277  44  44  44  46  45  ...  50   52  52   52  50

[16242 rows x 26 columns]

исходные данные:

In [45]: df.iloc[:, col_idx:]
Out[45]:
         ls    st    rs    lw    lf  ...    lb   lcb    cb   rcb    rb
0      89+2  89+2  89+2  93+2  93+2  ...  63+2  52+2  52+2  52+2  63+2
1      91+3  91+3  91+3  89+3  90+3  ...  61+3  53+3  53+3  53+3  61+3
2      84+3  84+3  84+3  90+3  89+3  ...  61+3  46+3  46+3  46+3  61+3
3       NaN   NaN   NaN   NaN   NaN  ...   NaN   NaN   NaN   NaN   NaN
4      83+3  83+3  83+3  89+3  88+3  ...  61+3  49+3  49+3  49+3  61+3
...     ...   ...   ...   ...   ...  ...   ...   ...   ...   ...   ...
18273  32+2  32+2  32+2  31+2  31+2  ...  45+2  46+2  46+2  46+2  45+2
18274  33+2  33+2  33+2  33+2  32+2  ...  46+2  47+2  47+2  47+2  46+2
18275  43+2  43+2  43+2  43+2  43+2  ...  47+2  49+2  49+2  49+2  47+2
18276  43+2  43+2  43+2  45+2  44+2  ...  48+2  49+2  49+2  49+2  48+2
18277  42+2  42+2  42+2  44+2  43+2  ...  48+2  50+2  50+2  50+2  48+2

[18278 rows x 26 columns]
→ Ссылка
Автор решения: CrazyElf

Конкретно в вашем коде ошибка просто в индексации, правильно так:

hemi = df[i].split('+')
total = int(hemi[0])+int(hemi[1]) # 1, а не 2

Потому что тот символ, по которому происходит разбиение функцией split, в выходной список не попадает:

print('85+2'.split('+'))
['85', '2']

И в данном случае вообще можно на индексы не завязываться, а преобразовывать в числа и суммировать все элементы списка разом, тогда это будет работать и для более длинных вариантов, например '423+23+343+34':

print(sum(map(int, '423+23+343+34'.split('+'))))
823
→ Ссылка