将.SAV文件转换为PANDAS DataFrame



我正在编写数据检查器以查看SPSS文件,并且需要在编程上处理不同的检查。第一步是访问SPSS文件,将其转换为PANDAS DataFrame,然后从那里运行我的支票。我发现这样做的唯一方法是通过RPY2。不幸的是,我几乎不知道R,并且无法在下面的任何解决方案上工作。任何帮助/文学都将不胜感激。

我已经从其他帖子中提取了一些东西,并创建了以下内容:

使用RPY2

from rpy2.robjects import pandas2ri
from rpy2.robjects import r
from pathlib import Path
import pyreadstat
pandas2ri.activate()
w = r('foreign::read.spss("%s", to.data.frame=TRUE)' % filename)
df = pandas2ri.ri2py(w)
df.head()
w.head()

错误:

rpy2.rinterface_lib.embedded.RRuntimeError: Error in foreign::read.spss("path to test.sav",  : 
  error reading system-file header

使用pyreadstat(这给了我列,但是当我尝试获取基础数据时,错误(

    meta = pyreadstat.read_sav(filename, metadataonly=True)
    cols = [x for x in meta[0]]
    df, meta = pyreadstat.read_sav(filename, usecols=cols)
    print(df)

错误:

pyreadstat._readstat_parser.PyreadstatError: STRING type with value 4/23/19 17:50 with date type

更新:

现在使用避风港,但仍会遇到错误:

rdf = r(f'haven::read_sav("{filename}")')

错误:

ValueError: Invalid value NaN (not a number)

我使用pyreadstat,您的第二个选项:

df, metadata = pyreadstat.read_sav("path to file", metadataonly=True)

这将返回一个空的DF(仅列的名称(和所有元数据。使用metadata.variable_value_labels,您将获得带有变量值的字典。

df, metadata = pyreadstat.read_sav("path to file", apply_value_formats=True) 

这将返回已更换的所有值的DF。

这可能会帮助https://ofajardo.github.io/pyreadstat_documentation/_build/html/index.html

要在pyreadstat上构建/更新DieGoc的答案,如果安装了pyreadstat,则可以使用pd.read_spss。因此,这很容易:

df = pd.read_spss("path_to_sav_file.sav")

再次,您需要pyreadstat才能使用pd.read_spss,因此,如果出现错误告诉您安装pyreadstat,请继续做告诉您的事情。对于Ultra Noobers:

$ pip install pyreadstat

$ conda install pyreadstat

而不是您可以使用scipy.io.io.readsav库将.sav文件转换为字典

scipy.io.readsav(file_name, idict=None, python_dict=False,
 uncompressed_file_name=None, verbose=False)

然后,字典可以轻松地转换为pandas dataframe。

我将使用savreaderWriter软件包:

pip install savReaderWriter --upgrade
import pandas
import savReaderWriter
with savReaderWriter.SavReader('mydata.sav', ioUtf8 = True) as reader:
    df = pandas.DataFrame(reader.all(), columns = [s.decode('CP1252') for s in reader.header])
df.head()

最新更新