【问题标题】:I can't delete cases from .sav files using spss with python我无法使用带有 python 的 spss 从 .sav 文件中删除案例
【发布时间】:2017-05-22 20:16:30
【问题描述】:

我有一些 .sav 文件要检查是否存在错误数据。我所说的不良数据与问题无关。我已经使用 spss 模块在 python 中编写了一个脚本来检查案例,如果它们不好则删除它们。我通过定义一个数据集对象然后获取它的案例列表来在数据步中做到这一点。然后我使用

del datasetObj.cases[k] 

删除数据步骤中的问题案例。

这是我的问题:

假设我有一个数据集 foo.sav,它是 spss 中的活动数据集,那么我可以运行类似的东西:

BEGIN PROGRAM PYTHON.
import spss
spss.StartDataStep()
datasetObj = spss.Dataset()
caselist = datasetObj.cases
del caselist[k]
spss.EndDataStep()
END PROGRAM.

从 spss 客户端中,它将从数据集 foo.sav 中删除案例 k。但是,如果我使用 foo.sav 的目录作为工作目录运行以下内容:

import os, spss

pathname = os.curdir()

foopathname = os.path.join(pathname, 'foo.sav')

spss.Submit("""
GET FILE='%(foopathname)s'.
DATASET NAME file1.
DATASET ACTIVATE file1.
""" %locals())

spss.StartDataStep()
datasetObj = spss.Dataset()
caselist = datasetObj.cases
del caselist[3]
spss.EndDataStep()

从命令行,那么它不会删除大小写 k。获取值的类似代码可以正常工作。例如,

print caselist[3]

将打印大小写 k(当它在数据步骤中时)。我什至可以更改案例中各个条目的值。但它不会删除案例。有什么想法吗?

我是python和spss的新手,所以可能有一些我看不到的东西对其他人来说是显而易见的;因此我为什么要问这个问题。

【问题讨论】:

    标签: python spss


    【解决方案1】:

    您的第一段代码对我不起作用。我对其进行了如下调整以使其正常工作:

    BEGIN PROGRAM PYTHON.
    import spss
    spss.StartDataStep()
    datasetObj = spss.Dataset()
    del datasetObj.cases[k]
    spss.EndDataStep()
    END PROGRAM.
    

    请注意,在您的代码中,caselist 只是一个列表,其中包含从 SPSS 中的 datasetObj 获取的值。属性.cases 属于datasetObj

    使用spss.Submit,您还可以使用SPSS 命令SELECT IF 删除案例(或者实际上,不选择它们)。例如,如果您的文件有一个名为 age 的变量(列),其值范围为 0 到 100,您可以使用以下方法删除所有年龄低于(在 SPSS:lt<)25 的案例:

    BEGIN PROGRAM PYTHON.
    import spss
    spss.Submit("""
    SELECT IF age lt 25.
    """)
    END PROGRAM.
    

    不要忘记添加一些代码来保存编辑后的文件。

    【讨论】:

    • 感谢您的回答,并指出代码中存在错误。可悲的是,这并没有导致我的原始代码出现问题。我遇到的问题是运行第二个代码块。它实际上并没有删除案例,但我不知道为什么。在运行一些测试时,我还添加了一些代码以在删除案例后保存文件,但它仍然没有工作。
    • 哦,等等,我忽略了您对字符串替换的使用。请看diveintopython.net/native_data_types/formatting_strings.html
    【解决方案2】:

    caselist 实际上不是包含数据集值的常规列表。虽然它的接口是列表接口,但它实际上直接与数据集一起工作,因此它不包含值的列表。它只是访问 SPSS 端的操作来检索、更改或删除值。最重要的区别在于,由于 Statistics 不会将数据保存在内存中,因此 caselist 的大小不受内存限制。

    但是,如果您尝试使用循环遍历案例
    范围(spss.GetCaseCount())
    并删除一些,循环最终会失败,因为实际的案例计数反映了删除,但循环限制并没有反映这一点。如果删除了较早的案例,则 datasetObj.cases[k] 可能不是您期望的情况。因此,您需要跟踪删除并适当调整限制或 k 值。

    HTH

    【讨论】:

    • 感谢您的回答。我并不真正关心不断变化的案例列表,我真的只想制作一个循环遍历案例的 for 循环,因此案例索引最终无关紧要。我的问题是试图让我上面的第二个代码块删除案例。再次感谢。
    • del 命令应该删除上面代码中的案例 3,但另一种方法是生成一个新的 0/1 变量来标记要删除的案例并应用 SELECT IF。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多