36
votes

Is there a module for Python to open IBM SPSS (i.e. .sav) files? It would be great if there's something up-to-date which doesn't require any additional dll files/libraries.

4
possible duplicate of Exporting to SPSS files in Python Django? If you want there is also a recipe on active-stateBakuriu
Hi, Bakuriu. It's not a duplicate, as I'm not referencing the Django framework, I'm talking about opening, as opposed to exporting/writing a file, and I mentioned the preference for something recent which doesn't require external libraries/dlls. There's some common ground between the questions, but they can elicit different, as well as similar, responses. Thanks for the link, but again, I'm trying to avoid dll files, if possible.Lamps1829
The other answer cites Django, but it actually has nothing to do with it. Since Exporting requires the ability to write a file, the chances that you can also read it are high. Reading around I strongly believe you have only one choice: use the .dll released by IBM. I can't find any open specification for that file format, which means that the only way to read those file is to use IBM's libraries. You can always try to reverse-engineer the format, but that would take much more time and effort.Bakuriu
Thanks, Bakuriu. It's unfortunate, but as you said, it is looking likely that IBM's .dll release is the thing to use.Lamps1829

4 Answers

30
votes

I have released a python package "pyreadstat" that reads SPSS (sav, zsav and por), Stata and SAS files. It is a wrapper around the C library ReadStat so it is very fast. Readstat is the library used in the back of the R library Haven, which is widely used and very robust.

The package is autocontained. It does not require using R (no need to install an aditional application) and it does not depend on IBM dlls or other external libraries.

For example, in order to read a SPSS sav file you would do:

import pyreadstat

df, meta = pyreadstat.read_sav("/path/to/sav/file.sav")

df is a pandas dataframe. Meta contains metadata such as variable labels or value labels. read_sav reads both sav and zsav (compressed) files. There is also a function read_por for old por (portable) files.

You can find it here: https://github.com/Roche/pyreadstat

11
votes

Depending on what you want to do--process data using R-related commands from rpy2, or switch to Python--the solution provided by @Spacedman on a related thread might easily be adapted to suit your needs.

Otherwise, Pandas includes a convenient wrapper for rpy2. Here is an example of use with Peat and Barton's weights.sav data set:

>>> import pandas.rpy.common as com
>>> filename = "weights.sav"
>>> w = com.robj.r('foreign::read.spss("%s", to.data.frame=TRUE)' % filename)
>>> w = com.convert_robj(w)
>>> w.head()
     ID  WEIGHT  LENGTH  HEADC  GENDER  EDUCATIO              PARITY
1  L001    3.95    55.5   37.5  Female  tertiary  3 or more siblings
2  L003    4.63    57.0   38.5  Female  tertiary           Singleton
3  L004    4.75    56.0   38.5    Male    year12          2 siblings
4  L005    3.92    56.0   39.0    Male  tertiary         One sibling
5  L006    4.56    55.0   39.5    Male    year10          2 siblings
9
votes

As a note for people findings this later (like me): pandas.rpyhas been deprecated in the newest versions of pandas (>0.16) as noted here. That page includes information on updating code to use the rpy2 interface.

6
votes

When you have pandas >= 0.25.0 you can now finally just do pd.read_spss():

# you need pandas >= 0.25.0 for this    
import pandas as pd
df = pd.read_spss('your_spss_file.sav')

This has library pyreadstat as a requirement, so you might have to install that first:

pip install pyreadstat

Extra info on the parameters of pd.read_spss():

Parameters
----------
path