3
\$\begingroup\$

I have a dictionary:

x = {'[a]':'(1234)', '[b]':'(2345)', '[c]':'(xyzad)'}

and a dataframe

df = pd.DataFrame({'q':['hey this is [a]', 'why dont you [b]', 'clas is [c]']})

I want to append the values from dictionary to the corresponding keys.

My expected output is:

                       q                                                                                                             
0   hey this is [a](1234)                                                                                                             
1  why dont you [b](2345)                                                                                                             
2      clas is [c](xyzad) 

Here's my solution:

x = {k: k+v for k,v in x.items()}

def das(data):
    for i in x.keys():
        if i in data:
            data = data.replace(i, x[i])
    return data

df['q'] = df['q'].apply(lambda x: das(x))
print(df)

Is there a way to improve this?

I have to update a dictionary by appending a key infront of values. Then I use apply to replace the values.

I am looking for more efficient solution.

\$\endgroup\$
2
  • \$\begingroup\$ Are the keys always in the form shown in this example, i.e. surrounded by []? \$\endgroup\$
    – Graipher
    Feb 19, 2019 at 15:24
  • \$\begingroup\$ @Graipher yes..it's like markdown used in SE \$\endgroup\$
    – Sociopath
    Feb 20, 2019 at 4:32

1 Answer 1

1
\$\begingroup\$

There is an alternative way using the str functions of pandas.Series, which has the advantage that they are usually faster. In this case you can use pandas.Series.str.replace, which can take a regex to match strings against and a callable to replace them with, which gets passed the regex match object:

def repl(m):
    k = m.group()
    return k + x[k]

df.q.str.replace(r'\[.*\]', repl)
# 0     hey this is [a](1234)
# 1    why dont you [b](2345)
# 2        clas is [c](xyzad)
# Name: q, dtype: object

This uses the fact that your keys to replace seem to follow a pattern, though, and works only as long as you can write a regex to capture it. In that sense your solution is more general.

One thing that you can change in your approach is the check for if i in data. It is superfluous, since str.replace will just ignore it if the string to replace does not appear in the string (it has to search linearly through the whole string to figure that out, but so does i in data).

In addition, instead of iterating over the keys with for i in x.keys():, you can just do for i in x:. But since you also need the value, you can directly do for key, repl in x.items(): data = data.replace(key, repl).

\$\endgroup\$
1
  • \$\begingroup\$ Thanks and nice catch that if statement in useless in that for loop. \$\endgroup\$
    – Sociopath
    Feb 20, 2019 at 5:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.