Error opening model as mat file in python? - python

I am trying to open a model.mat file in python as follow.
But I am getting an error: "AttributeError: 'dict' object has no attribute 'reactions'"
The file supposed to be a full model and I was expecting to inspect the number of reactions etc.
import scipy.io as sio
model= sio.loadmat("C:/Users/mydirectory/myfile.mat")
print(len(model.reactions))
print(len(model.metabolites))
print(len(model.genes))

Method which you use returns dict (https://docs.scipy.org/doc/scipy/reference/generated/scipy.io.loadmat.html )
Only way to access dict values is by:
model["reactions"]
If you really need to use get values as you described you can create Namespace for that dict e.g.:
from argparse import Namespace
ns = Namespace(**model)
and now ns.reactions will work

Related

How to works pickle dataframe inside

I wonder how the module "pickle" save and load objects. I saved a file with a dataframe object on the disk,
import pandas as pd
import pickle
df = pd.read_excel(r".\test.xlsx")
with open("o.pkl", "wb") as file:
pickle.dump(df, file)
then I uninstalled pandas and tried to load the object dataframe from file, but i get error "Exception has occurred: ModuleNotFoundError
No module named 'pandas'":
import pickle
with open("o.pkl", "rb") as file:
e = pickle.load(file)
my question is, does the pickle module somehow use pandas when loading an df? If so how is it done?
Pickle by default will go and import the class.
In this case, if you do not have pandas installed when you run the second snippet, it won't work by default (see below for more info on that default behaviour).
Quick primer on pickling
Essentially, everything in Python is an instance of a class, in some shape or form.
When you make a DataFrame, such as when you use pandas.read_excel, you create an instance of a DataFrame class. To create that class you need:
the class definition (containing information about methods and attributes)
something that creates the instance from some input data
You can create instances of a class normally by directly instantiating the class, or by using another method/function. Example:
# This makes a string, '12345' by directly invoking the str constructor
s = str(12345)
# This makes a list by using the split method of the string
l = s.split('3')
Pickle works just the same. When you unpickle, you need the class definition as well as the function which transforms some input data (your .pkl file) into the instance.
The class definition will be available in the pickled data, but none of the other supporting imports + code outside of the class will be.
This means that even if you override the default behaviour, while you might be able to make a DataFrame, your DataFrame won't work because you're missing pandas. When you try to invoke a method on the DataFrame, Python will try to access code that doesn't live in the original class definition. This code lives in other modules in the pandas module, and so this will never be captured in the pickle -- your code will then become quite unhappy at this point.
Can I override the default behaviour for unpickling?
Yes, you can do this -- you can override the import behaviour by using a custom unpickler. That's described here in the Python doc: restricting globals (Python official doc).
I've run into a similar thing before where it needed a specific pandas version, but I didn't investigate. Running across your post here, I read some of the documentation and came across this line:
When a class instance is unpickled, its __init__() method is usually not invoked. The default behaviour first creates an uninitialized instance and then restores the saved attributes.
https://docs.python.org/3.8/library/pickle.html#pickle-inst
So to unpickle an arbitrary class instance, it has to be able to access the initialization method of that class. If the class isn't present, it can't do that.
That same page also says:
Similarly, when class instances are pickled, their class’s code and data are not pickled along with them. Only the instance data are pickled.
If I make a pandas DataFrame, I can access df.__class__ which will return pandas.core.frame.DataFrame
Putting this all together on that page, here's what I think happens:
Pickling df saves the instance data, which includes the __class__ attribute
Unpickling goes and looks for this class to access its __setstate__ method
If the module containing this class definition can't be found: error!
Short answer: it saves that information.

object is not callable but I do not know how to divide the module into each other

import mains
print(mains.hi())
import parsogv2
print(parsogv2.gets())
priliv = mains()/parsogv2()
I have this trouble 'module' object is not callable. I want to split the values I get in modules How to do it better ? Combine them into one module or can I do as I wanted in the code ?
If what you've been trying to do is divide the return values of mains.hi() and parsogv2.gets(), then what you should be doing is:
priliv = mains.hi()/parsogv2.gets()
The error you've been receiving, informing you that a module is not callable, is a result of your attempt to call the actual modules (mains and parsogv2) instead of the functions they contain (mains.hi and parsogv2.gets), which I assume is what you were going for.

How to specify the object type so it is recognized prior to running the code in Python?

Suppose I have the following code excerpt:
import pickle
with open('my_object.pkl','r') as f:
object = pickle.load(f)
My question is:
Suppose object is from a class I defined previously, how can I specify this in the code such that my interpreter knows prior to running the code what the object class is ? My goal here is to have the auto-completion of my IDE (I use VSCode) recognize the object so I can auto-complete and easily search the methods and attributes of that object.
It depends on the version of Python and IDE, but in general looks like an additional statement with assertion instance type is the only way so far. This will trigger VS autocomplete settings
import pickle
with open('my_object.pkl','r') as f:
object = pickle.load(f)
assert isinstance(object, YourType)
# and now you can use autocompletion with the object
The following issue is tracking that feature: #82.

ppf function missing from t

I'm trying to reproduce the example given here: http://jkitchin.github.io/blog/2013/02/12/Nonlinear-curve-fitting-with-parameter-confidence-intervals/
So I imported the module like that:
from scipy.stats.distributions import t
But when I try to a simple
tval = t.ppf(1-alpha/2, dof)
I have the exception:
AttributeError: 'numpy.ndarray' object has no attribute 'ppf'
So t is a numpy.ndarray. But if I read the doc, it is supposed to be an object, with methods.
Do you have an idea about what's happening ?
It seems you may have overwritten the variable t with an array somewhere. What your error message means is that t is a numpy.ndarray which has no ppf method. The t you intended to import shouldn't be an ndarray but rather a distribution generator.
Either find where it became an array and use another name there, or import with better names.
For example, try changing your import line to this:
from scipy.stats import distrbutions as dists
and then change the problem line to:
tval = dists.t.ppf(1-alpha/2, dof)
Alternatively:
from scipy.stats.distributions import t as tdist
tval = tdist.ppf(1-alpha/2, dof)

How to decipher this cPickle error?

I have a pickled file called classifier.pkl that I am trying to load into another module. However, I get an error I don't understand.
My code to pickle:
features = ['bob','ice','snowing'] #... shortened for exposition's sake
def extract_features(document):
return {'contains(%s)'% word: (word in set(document))
for word in all_together_word_list}
training_set = classify.util.apply_features(extract_features,tweets[0])
classifier = NaiveBayesClassifier.train(training_set)
cPcikle.dump(open('cocaine_classifier.pkl','wb'))
My code to unpickle:
features, extract_features, classifier =
cPickle.load(open('cocaine_classifier.pkl','rb'))
My error:
AttributeError: 'module' object has no attribute 'extract_features'
A while ago I made the .pkl file by pickling three things:
features : list
extract_features : function
classifier : instance of NLTK Naive Bayes Classifier
Puzzlingly, I get the same error with the following code:
x = cPickle.load(open('cocaine_classifier.pkl','rb'))
Why can't I retrieve three things? Even when I'm not trying to unpack the tuple?
Update
As NPE pointed out the path of the function to be unpickled must exactly match the function into which its being unpickled. I was debugging and Terminal and so from mod import * loads everything into the namespace whereas import mod as m does not.
The problem is that when you pickle a function, only the (fully-qualified) name of the function is pickled, not the function itself. This means that you have to have the function definition in place when you're unpickling.
Did you by any chance mean to pickle the result of calling extract_features?

Categories