【问题标题】:Series string replace with contents from another series (without using apply)系列字符串替换为另一个系列的内容(不使用应用)
【发布时间】:2023-03-11 06:28:01
【问题描述】:

为了优化,我想知道是否可以在不使用apply的情况下在一列中使用另一列中相应行的内容进行更快的字符串替换。

这是我的数据框:

data_dict = {'root': [r'c:/windows/'], 'file': [r'c:/windows/system32/calc.exe']}
df = pd.DataFrame.from_dict(data_dict)

"""
Result:
                           file         root
0  c:/windows/system32/calc.exe  c:/windows/
"""

使用以下申请,我可以得到我想要的:

df['trunc'] = df.apply(lambda x: x['file'].replace(x['path'], ''), axis=1)

"""
Result:
                           file         root              trunc
0  c:/windows/system32/calc.exe  c:/windows/  system32/calc.exe 
"""

但是,为了更有效地使用代码,我想知道是否有更好的方法。我已经尝试了下面的代码,但它似乎没有按我预期的方式工作。

df['trunc'] = df['file'].replace(df['root'], '')

"""
Result (note that the root was NOT properly replaced with a black string in the 'trunc' column):

                           file         root                         trunc
0  c:/windows/system32/calc.exe  c:/windows/  c:/windows/system32/calc.exe
"""

还有更有效的替代方案吗?谢谢!

编辑 - 以下几个示例的时间安排

# Expand out the data set to 1000 entries
data_dict = {'root': [r'c:/windows/']*1000, 'file': [r'c:/windows/system32/calc.exe']*1000}
df0 = pd.DataFrame.from_dict(data_dict)

使用应用

%%timeit -n 100
df0['trunk0'] = df0.apply(lambda x: x['file'].replace(x['root'], ''), axis=1)

100 次循环,3 次中的最佳:每个循环 13.9 毫秒

使用替换(感谢 Gayatri)

%%timeit -n 100
df0['trunk1'] = df0['file'].replace(df0['root'], '', regex=True)

100 次循环,最好的 3 次:每个循环 365 毫秒

使用 Zip(感谢 0p3n5ourcE)

%%timeit -n 100
df0['trunk2'] = [file_val.replace(root_val, '') for file_val, root_val in zip(df0.file, df0.root)]

100 次循环,3 次中的最佳:每个循环 600 µs

总的来说,这里看起来 zip 是最好的选择。感谢您的所有意见!

【问题讨论】:

    标签: python pandas replace


    【解决方案1】:

    使用与link类似的方法

    df['trunc'] = [file_val.replace(root_val, '') for file_val, root_val in zip(df.file, df.root)]
    

    输出:

                              file         root              trunc
    0  c:/windows/system32/calc.exe  c:/windows/  system32/calc.exe
    

    检查timeit:

    %%timeit
    df['trunc'] = df.apply(lambda x: x['file'].replace(x['root'], ''), axis=1)
    

    结果:

    1000 loops, best of 3: 469 µs per loop
    

    使用 zip:

    %%timeit
    df['trunc'] = [file_val.replace(root_val, '') for file_val, root_val in zip(df.file, df.root)]
    

    结果:

    1000 loops, best of 3: 322 µs per loop
    

    【讨论】:

    • 我想我从来没有想过使用列表理解和 zip。看起来这是禁食的解决方案!
    【解决方案2】:

    试试这个:

    df['file'] = df['file'].astype(str)
    df['root'] = df['root'].astype(str)
    df['file'].replace(df['root'],'', regex=True)
    

    输出:

    0    system32/calc.exe
    Name: file, dtype: object
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-31
      • 2018-08-30
      • 1970-01-01
      • 1970-01-01
      • 2020-03-07
      • 2021-05-15
      • 2019-06-06
      • 2020-02-03
      相关资源
      最近更新 更多