Оптимальный способ поиска и замены нечисловых данных в большом фрейме данных - PullRequest
0 голосов
/ 18 июня 2020

У меня большой фрейм данных с более чем 12 миллионами строк, и один из столбцов timelogs представляет собой сочетание букв, цифр c и некоторых специальных символов. Я хочу удалить все нечисловые символы из timelogs, прежде чем окончательно преобразовать этот столбец в datetime, выполнив pd.to_datetime(df['timestr']). Я выполняю операцию ниже, чтобы удалить нечисловые символы, и для выполнения этой операции требуется 30-45 минут. :

df.loc[:, 'timestr'] = df['timelogs'].str.replace('([^0-9]+)', '')

Есть ли способ добиться этого быстрее? путь?

1 Ответ

1 голос
/ 18 июня 2020

Вы можете использовать translate со следующей таблицей перевода:

import string
tt = str.maketrans('', '', string.ascii_letters + string.punctuation + string.whitespace)

В моем тесте с серией из 100К букв и цифр c строк длиной 20 это примерно 35 % быстрее, чем replace.

x = np.random.choice(list(string.ascii_letters + string.digits), [100_000, 20])
s = pd.Series([''.join(x[i]) for i in range(len(x))])

    0        4r7xNfZyvbZjcg6sb9UY
    1        GqQywPb0JCHcvRXWV8yV
    2        8zyOOyC38qoztCZzshoP
    3        iemM6xXIkf6xaoAPFlSr
    4        uJYCeuftjkDQSwNchYU2
                     ...
    99995    ugH4TvzuEvB5f2Cp5Mlt
    99996    SYXsz75l9qApOHJDoIF9
    99997    34Xyz45JDx1HFojpWTL2
    99998    BSyhzbx57H9V237PZgqp
    99999    q9Bo9lwKw6O7y7G9G5aQ
    Length: 100000, dtype: object

%timeit s.apply(lambda x: "".join([c for c in x if c.isdigit()]))
#174 ms ± 960 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit s.str.replace('([^0-9]+)', '')
#136 ms ± 443 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit s.str.translate(tt)
#88.5 ms ± 348 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

Чем длиннее струны, тем лучше translate по отношению к replace:

enter image description here

...