将 SAS 数据文件导入 python 数据框

Import SAS data file into python data frame

我正在处理一个数据集 (PSID),它以 SAS 格式提供数据(一个 .txt 和另一个包含解释数据说明的文件)。我在 Python 中找不到任何内容来读取此类数据。

有人知道已有的 module/script 可以读取 SAS 数据吗?

Edit(从评论添加到答案):数据在 ascii/text 中,一行数据的开头如下所示:

3 10 1015000 150013200 00 002500 00 00

当您可以选择下载 SAS 数据集时,您通常也可以选择下载 Stata 数据集(顺便说一句,PSID 确实是这种情况)。在这种情况下,最简单的方法可能是使用 read_stata 导入(这可能会在未来发生变化,但我相信截至今天,这是一个非常准确的陈述)。

下载文本文件(通常称为文本、ascii 或 csv)不太方便,但几乎总是一种选择。这些往往有两种形式:分隔(用逗号或制表符),或 space 分隔(柱状或表格)。如果文件以逗号或制表符分隔,请使用 read_csv 并根据需要设置分隔符。如果它是 space 分隔的或表格的,那么使用 read_csv 可能会好运,或者使用 read_fwfread_table 可能会更好。取决于变量类型和格式。

据我所知,@hd1 提到的 sas7bdat 似乎运行良好,但还不是 pandas 的一部分。出于这个原因,我倾向于默认为 read_stataread_csv,但希望 sas7bdat 也能很好地工作,也许将来会被引入 pandas。另外,我想知道 sas7bdat 的速度。 read_csv 长期以来一直非常快,而 read_stata 在最新版本中非常快(我相信从 15.0 开始)。我不确定 sas7bdat?

的速度

查看您获得的 SAS 代码。您应该看到它的格式非常一致,以便您可以解析出变量名称和列以读取这些变量。例如在这篇论文中 https://psidonline.isr.umich.edu/Guide/FileStructure.pdf 你可以看到 INPUT 语句的形式是:

INPUT
    ER30001 2 - 5
    ER30002 6 - 8
    ER30642 1528 - 1532
    ER30643 1533 - 1534
...
;

所以只需阅读 SAS 程序并生成适当的 Python 即可使用相同的变量名读取文本文件。

数据固定在 table。固定意味着例如第 3 个值从每行的第 15 个字母开始,一直到第 114 个字母。

1.Open 您的 SAS 或 SPSS 输入语句。如果是 SAS,您会发现类似这样的内容:

@1  ANO_CENSO   5.  /*Ano do Censo*/
@6  PK_COD_ENTIDADE 9.  /*Código da Escola*/
@15 NO_ENTIDADE $Char100.   /*Nome da Escola*/
@115    COD_ORGAO_REGIONAL_INEP $Char5. /*Código do Órgão Regional de Ensino*/

左边的数字是列(字母数,其中相应的值)

2.In下面的脚本,填列,first是列名second元组是变量的第一个和最后一个letter/number的列。注意 SAS 从 1 开始计数,python 从 0 开始计数。

import pandas as pd

columns=(
('ANO', (0, 5)),
('CODE', (5, 14)),
('DESC_SITUACAO_FUNCIONAMENTO', (119, 134)),
('FK_COD_ESTADO', (176, 178)),
('SIGLA', (178, 181)),
)

df = pd.read_fwf('TS_ESCOLA.TXT', names=zip(*columns)[0], colspecs=zip(*columns)[1], header=None)

// pd.read_fwf与pandas的reader固定。

从版本 17 开始,Pandas 现在支持读取文件扩展名为 .xpt 的 sas 文件。有关其他详细信息,请参阅 this link 到 pandas 文档。

df = pd.read_sas('sas_xport.xpt')

所以我写了一个可以导入数据的包。可以在这里找到:

https://pypi.python.org/pypi/psid_py

这是我的第一个包裹,很抱歉工作草率。此外,它仅针对 PSID 数据集进行了测试,我确信其他 SAS 格式存在错误。不过,有总比没有好。

除了读取 sas 数据外,它还会为您构建一个面板数据,以防您喜欢那种东西。

我知道这是一个旧的 post 但是只是想提供一种有效的方法,如果有人通过 google.

到达此页面

我们可以使用 pyreadstat 来做同样的事情(可以获得数据和元数据)。

import pyreadstat
df, meta = pyreadstat.read_sas7bdat('/path/to/a/file.sas7bdat')

或使用以下代码保存 pandas 帧

pyreadstat.write_xport(df, "path/to/destination.xpt", file_label="test", column_labels=column_labels)

我知道这是一个很晚的回复,但我认为我的回答将对未来的读者有用。几个月前,当我不得不读取和处理 SAS 数据 SAS7BDATxpt 格式 SAS 数据时,我正在寻找可用于读取这些数据集的不同库和包,其中,我将图书馆入围如下:

  1. pandas(由于社区支持和 性能)
  2. SAS7BDAT(只能读取 SAS7BDAT 个文件,上次发布时间为 2019 年 7 月)
  3. pyreadstat(根据文档的有前途的性能加上读取元数据的能力)

在选择任何包之前,我做了一些性能基准测试,我发现 pyreadstatpandas 快,(好像它在读取文档中提到的数据时使用了多处理,但是我不太确定),而且与 pandas 相比,使用 pyreadstat 时内存消耗和占用空间要小得多,而且它能够读取元数据,甚至允许读取仅限 metadeta,所以我最终选择了 pyreadstat

使用pyreadstat读取的数据已经是dataframe的形式,所以不需要手动转换成pandasdataframe。

import pyreadstat

#for SAS7BDAT files
df, _ = pyreadstat.read_sas7bdat('some_file.sas7bdat')

#for xpt files
df, _ = pyreadstat.read_xpt('some_file.xport')

这是对 CDISC 的真实数据(原始数据和标准数据)执行的一些基准测试(将文件读取到数据帧的时间),文件大小从几 KB 到几 MB 不等,包括 xpt 和 sas7bdat 文件格式:

Reading ADAE.xpt 49.06 KB for 100 loops:
    Pandas Average time : 0.02232 seconds
    Pyreadstat Average time : 0.04819 seconds
----------------------------------------------------------------------------
Reading ADIE.xpt 27.73 KB for 100 loops:
    Pandas Average time : 0.01610 seconds
    Pyreadstat Average time : 0.03981 seconds
----------------------------------------------------------------------------
Reading ADVS.xpt 386.95 KB for 100 loops:
    Pandas Average time : 0.03248 seconds
    Pyreadstat Average time : 0.07580 seconds
----------------------------------------------------------------------------
Reading beck.sas7bdat 14.72 MB for 50 loops:
    Pandas Average time : 5.30275 seconds
    Pyreadstat Average time : 0.60373 seconds
----------------------------------------------------------------------------
Reading p0_qs.sas7bdat 42.61 MB for 50 loops:
    Pandas Average time : 15.53942 seconds
    Pyreadstat Average time : 1.69885 seconds
----------------------------------------------------------------------------
Reading ta.sas7bdat 33.00 KB for 100 loops:
    Pandas Average time : 0.04017 seconds
    Pyreadstat Average time : 0.00152 seconds
----------------------------------------------------------------------------
Reading te.sas7bdat 33.00 KB for 100 loops:
    Pandas Average time : 0.01052 seconds
    Pyreadstat Average time : 0.00109 seconds
----------------------------------------------------------------------------
Reading ti.sas7bdat 33.00 KB for 100 loops:
    Pandas Average time : 0.04446 seconds
    Pyreadstat Average time : 0.00179 seconds
----------------------------------------------------------------------------
Reading ts.sas7bdat 33.00 KB for 100 loops:
    Pandas Average time : 0.01273 seconds
    Pyreadstat Average time : 0.00129 seconds
----------------------------------------------------------------------------
Reading t_frcow.sas7bdat 14.59 MB for 50 loops:
    Pandas Average time : 7.93266 seconds
    Pyreadstat Average time : 0.92295 seconds

如您所见,对于 xpt 文件,读取文件的时间并没有更好,但对于 sas7bdat 文件,pyreadstat 的性能优于 pandas。

上述基准测试是在 pyreadstat 1.0.9、pandas 1.2.4 和 Python 3.7.5 上执行的。