0

I have a function which takes several arguments. One of the arguments refers to a data frame. Now I want to use this argument as both a data frame (which I am easily able to) and a string (which I am just not able to). By string I mean, I want to use the name of the data frame as a string.

def get_avg_spectrum(full_signal, fs, skip_samples = 0,...):
    code...
    ...
    ...
return output

result = get_avg_spectrum(full_signal = acc_x_g, fs = 5000, skip_samples = 0,...)

Here, "acc_x_g" refers to a Pandas series. So I want to use the whole series as well as the text "acc_x_g".

# the below doesn't work

full_signal.name
Out[104]: 'ACC'

# ACC is the name of the variable in the Pandas Series "acc_x_g"

I have a lot of series' to run this function for so the idea is to simply keep changing the "full_signal = xxx" parameter in the function. Can anyone please help with this.

Ankur
  • 35
  • 6
  • Wrong design and obvious XY problem. Instead of asking "how do I do Y" (which you - wrongly - think is the solution to X), describe the __real__ X problem instead. – bruno desthuilliers Mar 14 '19 at 14:28
  • I'm voting to close this question as off-topic because it's an obvious XY problem. – bruno desthuilliers Mar 14 '19 at 14:29
  • Well, isn't the problem of not being able to resolve a function parameter into both a dataframe and a string problem enough? For me, it is certainly the "Y" in "how do I do Y". – Ankur Mar 14 '19 at 14:46
  • To add, what is obvious to you may not be to others. I have only recently started working in Python so I think it is only natural to get stuck at a few places. – Ankur Mar 14 '19 at 14:50
  • Yoy may want to look for the definition of "XY problem". The "problem of not being able to resolve a function parameter into both a dataframe and a string" is not your REAL problem, it's what you think is the solution to your real problem. Instead of asking how to do this, explain WHY you'd want to do this (with enough context to make sense for someone that knows nothing about your project). Chances are there are much better ways... – bruno desthuilliers Mar 14 '19 at 15:50
  • NB: it's of course natural to get stuck sometimes when being new to python (or to programming FWIW) - actually we _all_ get stuck sometimes whatever the experience. I am not trying to chastise you for being a newbie or being stuck, I'm actually genuinely trying to help you. – bruno desthuilliers Mar 14 '19 at 15:55

2 Answers2

0

Based on this answer (and some testing), it doesn't sound possible (in your example, the code in the linked answer returns ["full_spectrum"] as the name rather than the desired ["acc_x_g"]).

However, one possibility is to pass a string with the name rather than the object. I'm not sure exactly how your code is set up, but something like this would work.

def get_avg_spectrum(full_signal, fs, skip_samples = 0,...):
    name = full_signal
    df = eval(full_signal)
    ...
    return(output)

result = get_avg_spectrum(full_signal = "acc_x_g", fs = 5000, skip_samples = 0,...)

EDIT: You might be able to combine these two (the linked answer, and what I posted above), if necessary. Again, it depends on how your objects were created, etc. But creating a handful of objects, looping over them to get their names, passing the names to the function... It's convoluted, but it could work.

cwotta
  • 63
  • 6
  • Please do NOT recommand using `eval` - it's dangerous, makes the code harder to debug and maintain and is almost never the appropriate solution ("almost never" => less than 0.00001%) – bruno desthuilliers Mar 14 '19 at 14:25
  • In this case the obvious proper equivalent solution is to maintain a dict of {name:df} and lookup this dict (not sure it would solve the OP's __real__ problem though). – bruno desthuilliers Mar 14 '19 at 14:30
  • Thanks @brunodesthuilliers. The above solution is working in my case. I also tried playing with inspect but to no avail. Will try your suggestion now. – Ankur Mar 14 '19 at 14:37
0

Given the comments on the other response, there's another way.

Create a dictionary where key is the name and the object is the value (could be automated using inspect as per the link). And then matching when the value == test_value.

The obvious choice is to simply pass the key to your function and have the function call the dictionary:

mydict = {"acc_x_g": acc_x_g}

def get_avg_spectrum(full_signal, fs, skip_samples = 0,...):
    df = mydict[full_signal]
    ...
    return(output)

result = get_avg_spectrum(full_signal = "acc_x_g", fs = 5000, skip_samples = 0,...)

But depending on your code, you may need to loop over the spectra in a specific order that was previously/automatically determined. If that's the case (where order matters), and you're unable to generate a list of that order, I leave the following solution. But careful! It assumes ALL of your pd.Series are unique!

mydict = {"acc_x_g": acc_x_g}

def get_avg_spectrum(full_signal, fs, skip_samples = 0,...):
    name = ""
    for k,v in mydict.items():
        if v.all() == full_signal.all():
            name = k

    ...
    return(output)

result = get_avg_spectrum(full_signal = acc_x_g, fs = 5000, skip_samples = 0,...)
cwotta
  • 63
  • 6