"Explicit is better than implicit"
...
"In the face of ambiguity, refuse the temptation to guess."
- PEP 20
Modifying a parameter within a function is not necessarily a bad thing. What is bad is to do so with no good reason for doing so. If you're clear with your function name and documentation that the parameter will be modified within the function, then that's fine. If the function modifies the parameter with no indication it's trying to do so, that's less fine.
In this case, your Way-1 is simpler and more explicit. It's obvious that the variable is going to be changed, and the way in which it's going to be changed can be determined easily by looking at the code.
Way-2 is worse, because the name change_b would imply that the parameter is going to be modified, and it's not. Returning a modified version of a parameter without modifying the original is a standard design pattern in python, but it's best to be explicit about it.
For example, python's built-in set data structure has counterpart methods: set.difference(other) and set.difference_update(other). In both cases, they do the same thing: compute the difference between this set and the given set. In the former case, that result is returned without modifying the original set. In the latter case, the original set is modified and nothing is returned. It's very straightforward to figure out which does what.
In general, you should probably avoid updating a value and returning that same value, because that's more ambiguous. Note how most python methods do one or the other, but not both (and those that do do both, like list.pop(), do so sensibly, with the returned object not being the object that was modified).
pandasworks in both ways. They create new data or they can update existing data if you addinplace=True. And this is nice way.globalto change data.