У меня есть CSV, например:
![enter image description here](https://i.stack.imgur.com/RBefh.png)
Где в первом столбце могут быть пробелы, но во втором и третьем нет пробелов в середине значений.
Значения столбца TO_REPLACE
следует заменить значениями в столбце VALUE_TO_COPY
при условии, что содержимое их ячеек совпадает со значением ячейки столбца TO_SEARCH
. Поэтому результат должен быть таким:
![enter image description here](https://i.stack.imgur.com/hN3J3.png)
Я написал скрипт:
import pandas as pd
import numpy as np
df = pd.read_csv(
filepath_or_buffer='mapping_test.csv',
delimiter=',',
dtype=str
)
to_replace = df['TO_REPLACE'].copy()
result = df['TO_REPLACE'].copy()
df = df.set_index('TO_SEARCH')
df.dropna(
how='all',
inplace=True
)
del df['TO_REPLACE']
for key, value in to_replace.iteritems():
try:
result[key] = df.loc[value, 'VALUE_TO_COPY']
except:
print('ERROR, not found KEY: {}'.format(key))
result_df = pd.DataFrame(
data={
'TO_REPLACE': result,
'VALUE_TO_COPY': list(df['VALUE_TO_COPY']) + [np.nan] * (len(result) - df['VALUE_TO_COPY'].size),
'TO_SEARCH': list(df.index) + [np.nan] * (len(result) - df['VALUE_TO_COPY'].size),
},
columns=['TO_REPLACE','VALUE_TO_COPY','TO_SEARCH'] # to preserve the column order
)
result_df.to_csv(
path_or_buf='mapping_result.csv',
index=False
)
Что я делаю в своем коде:
Я читаю данные из CSV в DataFrame
Я разделил DataFrame на две части. С одной стороны, я храню TO_REPLACE
как Series, а с другой стороны - DataFrame со столбцами VALUE_TO_COPY
и TO_SEARCH
. Я использую TO_SEARCH
в качестве индекса этого DataFrame.
Я перебираю столбец TO_REPLACE
, чтобы найти значения в столбце TO_SEARCH
. Если значения не совпадают, я сохраняю старое значение.
Я снова строю DataFrame с замененными значениями и сохраняю его в файле CSV.
Но это не очень эффективно. Мне нужно очень часто отображать тысячи значений, поэтому мне нужен более эффективный код. Есть идеи по улучшению моего кода?
Может быть, я мог бы использовать методы map
(для серии), apply
или applymap
(для DF). По крайней мере, я отбросил apply
, потому что он работает на всю строку за раз, а applymap
работает на весь DataFrame. Возможно, наиболее полезным является map
, но я думаю, что он перебирает все значения, как я делал вручную. Другой возможный вариант, который я рассмотрел, - это метод replace
, но я прочитал, что map
быстрее.