Package: a-pandas-ex-fast-string
Up to 4x faster than Series.str.contains / Series.eq - can handle Unicode!pipinstalla-pandas-ex-fast-stringfroma_pandas_ex_fast_stringimportpd_add_fast_stringimportpandasaspdpd_add_fast_string()df2=pd.read_csv("https://raw.githubusercontent.com/pandas-dev/pandas/main/doc/data/titanic.csv",dtype="string",)# To check if it can handle unicode stringsdf2.Name.iloc[0]+="ö"df2.Name.iloc[10]+="ä"df2.Name.iloc[20]+="ü"# converts the whole dataframedf900=pd.Q_convert_to_fast_string(df2.copy())dfone=df2.copy()# converts one columndfone.Cabin.ds_update_fast_string()# Let's create some DataFrames of different sizesdf9000=pd.Q_convert_to_fast_string(pd.concat([df2.copy()for_inrange(10)],ignore_index=True))df90000=pd.Q_convert_to_fast_string(pd.concat([df2.copy()for_inrange(100)],ignore_index=True))df900000=pd.Q_convert_to_fast_string(pd.concat([df2.copy()for_inrange(1000)],ignore_index=True))df9000000=pd.Q_convert_to_fast_string(pd.concat([df2.copy()for_inrange(10000)],ignore_index=True))%timeitdf900.loc[df900.Name.s_string_contains('y')|df900.Name.s_string_is('Montvila, Rev. Juozas')]%timeitdf900.loc[df900.Name.str.contains('y',regex=False)|(df900.Name=='Montvila, Rev. Juozas')]604µs±9.09µsperloop(mean±std.dev.of7runs,1,000loopseach)997µs±13.2µsperloop(mean±std.dev.of7runs,1,000loopseach)%timeitdf9000.loc[df9000.Name.s_string_contains('y')|df9000.Name.s_string_is('Montvila, Rev. Juozas')]%timeitdf9000.loc[df9000.Name.str.contains('y',regex=False)|(df9000.Name=='Montvila, Rev. Juozas')]1.15ms±15.2µsperloop(mean±std.dev.of7runs,1,000loopseach)2.77ms±11.2µsperloop(mean±std.dev.of7runs,100loopseach)%timeitdf90000.loc[df90000.Name.s_string_contains('y')|df90000.Name.s_string_is('Montvila, Rev. Juozas')]%timeitdf90000.loc[df90000.Name.str.contains('y',regex=False)|(df90000.Name=='Montvila, Rev. Juozas')]6.45ms±77.4µsperloop(mean±std.dev.of7runs,100loopseach)20.7ms±166µsperloop(mean±std.dev.of7runs,10loopseach)%timeitdf900000.loc[df900000.Name.s_string_contains('y')|df900000.Name.s_string_is('Montvila, Rev. Juozas')]%timeitdf900000.loc[df900000.Name.str.contains('y',regex=False)|(df900000.Name=='Montvila, Rev. Juozas')]60.5ms±853µsperloop(mean±std.dev.of7runs,10loopseach)206ms±840µsperloop(mean±std.dev.of7runs,1loopeach)%timeitdf9000000.loc[df9000000.Name.s_string_contains('y')|df9000000.Name.s_string_is('Montvila, Rev. Juozas')]%timeitdf9000000.loc[df9000000.Name.str.contains('y',regex=False)|(df9000000.Name=='Montvila, Rev. Juozas')]596ms±11.8msperloop(mean±std.dev.of7runs,1loopeach)2.06s±2.5msperloop(mean±std.dev.of7runs,1loopeach)# Good news: it can handle unicode characters!df9000.loc[df9000.Name.s_string_contains('ö')].NameOut[14]:0Braund,Mr.OwenHarrisö891Braund,Mr.OwenHarrisö1782Braund,Mr.OwenHarrisö2673Braund,Mr.OwenHarrisö3564Braund,Mr.OwenHarrisö4455Braund,Mr.OwenHarrisö5346Braund,Mr.OwenHarrisö6237Braund,Mr.OwenHarrisö7128Braund,Mr.OwenHarrisö8019Braund,Mr.OwenHarrisöName:Name,dtype:string# Bad news: every time you modify a Series, you have to update it:df9000.loc[df9000.Name.s_string_contains('ö')].Name0Braund,Mr.OwenHarrisö891Braund,Mr.OwenHarrisö1782Braund,Mr.OwenHarrisö2673Braund,Mr.OwenHarrisö3564Braund,Mr.OwenHarrisödf9000.loc[df9000.Name.s_string_contains('ö'),"Name"]=df9000.loc[df9000.Name.s_string_contains('ö'),"Name"]+'Ä'# updatingdf9000.Name0Braund,Mr.OwenHarrisöÄ1Cumings,Mrs.JohnBradley(FlorenceBriggsTh...2Heikkinen,Miss.Lainadf9000.loc[df9000.Name.s_string_contains('ö'),"Name"]# Exception because ds_update_fast_string was not calledTraceback(mostrecentcalllast):File"C:\Users\Gamer\anaconda3\envs\dfdir\lib\site-packages\IPython\core\interactiveshell.py",line3398,inrun_codeexec(code_obj,self.user_global_ns,self.user_ns)File"<ipython-input-7-2b0dfaf8b41c>",line1,in<cellline:1>df9000.loc[df9000.Name.s_string_contains('ö'),"Name"]File"C:/Users/Gamer/anaconda3/envs/dfdir/a_pandas_string_search.py",line133,insearch_containswordtosearchbin,columntosearch=_get_col_word(File"C:/Users/Gamer/anaconda3/envs/dfdir/a_pandas_string_search.py",line103,in_get_col_wordreturnwordtosearchbin,series._stringser.__array__()AttributeError:'NoneType'objecthasnoattribute'__array__'df9000.Name.ds_update_fast_string()# Necessary after changing a Series# you can also update the whole DataFrame: df9000 = df9000.ds_update_fast_string()# Be careful: df9000.Name.ds_update_fast_string() returns None (inplace)# df9000.ds_update_fast_string() returns a DataFramedf9000.loc[df9000.Name.s_string_contains('ö'),"Name"]# Now it is working!0Braund,Mr.OwenHarrisöÄ891Braund,Mr.OwenHarrisöÄ1782Braund,Mr.OwenHarrisöÄ2673Braund,Mr.OwenHarrisöÄ