Ответ 1
Сначала рассмотрим разницу между .map(str.strip)
и .str.strip()
(второй и третий случай).
Поэтому вам нужно понять, что делает str.strip()
под капотом: на самом деле он делает несколько map(str.strip)
, но использует пользовательскую функцию map
, которая будет обрабатывать отсутствующие значения.
Поэтому, если .str.strip()
больше, чем .map(str.strip)
, следует ожидать, что этот метод будет всегда медленнее (и, как вы показали, в вашем случае 2x медленнее).
Использование метода .str.strip()
имеет свои преимущества при автоматической обработке NaN (или обработке других нестрочных значений). Предположим, что столбец "id" содержит значение NaN:
In [4]: df['id'].map(str.strip)
...
TypeError: descriptor 'strip' requires a 'str' object but received a 'float'
In [5]: df['id'].str.strip()
Out[5]:
0 NaN
1 as asd
2 asdsa asdasdas
...
29997 asds
29998 as asd
29999 asdsa asdasdas
Name: id, dtype: object
Как указывает @EdChum, вы действительно можете использовать map(str.strip)
, если вы уверены, что у вас нет значений NaN, если важна разница в производительности.
Возвращаясь к другой разности fcr['id'].astype(str).map(str.strip)
. Если вы уже знаете, что значения внутри серии являются строками, вызов astype(str)
, конечно, лишний. И именно этот вызов объясняет разницу:
In [74]: %timeit df['id'].astype(str).map(str.strip)
100 loops, best of 3: 10.5 ms per loop
In [75]: %timeit df['id'].astype(str)
100 loops, best of 3: 5.25 ms per loop
In [76]: %timeit df['id'].map(str.strip)
100 loops, best of 3: 5.18 ms per loop
Обратите внимание, что в случае, если у вас есть нестроковые значения (NaN, числовые значения,...), использование .str.strip()
и .astype(str).map(str)
не даст такого же результата:
In [11]: s = pd.Series([' a', 10])
In [12]: s.astype(str).map(str.strip)
Out[12]:
0 a
1 10
dtype: object
In [13]: s.str.strip()
Out[13]:
0 a
1 NaN
dtype: object
Как вы можете видеть, .str.strip()
вернет нестроковые значения как NaN вместо преобразования их в строки.