Python模块savReaderWriter导致Segmentation错误

时间:2014-11-12 19:31:04

标签: python spss

我在Ubuntu上使用Python 2.7。我有一个编写SPSS .sav文件的脚本。 如果我使用ValueLabels数字作为这样的键:

{1: 'yes', 2: 'no'}

以下行导致分段错误:

with savReaderWriter.SavWriter(sav_file_name, varNames, varTypes, valueLabels=value_labels, ioUtf8=True) as writer:

但是,如果我的键是这样的字符串:

{'1': 'yes', '2': 'no'}

我没有得到Segmentation错误,我的脚本运行正常。问题当然是我需要键才能成为数字。我该如何解决或解决这个问题。

提前谢谢。

-RLS

2 个答案:

答案 0 :(得分:1)

只需转换dict,然后再将其传递给SavWriter

labels = {str(key): value for key, value in value_labels.items()}

或早期版本的python:

labels = dict((str(key), value) for key, value in value_labels.items())

但是,最好的长期解决方案是重新计算代码,以便密钥不必是数字。

<强>更新

如果dicts是嵌套的,那么试试这个:

labels = {str(key): {str(key): value for key, value in value.items()}
          for key, value in value_label.items()}

答案 1 :(得分:1)

根据您是指定数字(varType == 0)还是字符串(varType > 0,其中varType是字符串值的字节长度),SPSS I的以下两个C函数之一/ O库被称为:

  • int spssSetVarNValueLabel(int handle, const char * varName, double value, const char * label)
  • int spssSetVarCValueLabel(int handle, const char * varName, const char * value, const char * label)

请注意ctypes.c_double接受浮点数和整数,因此数值变量的值不一定必须指定为浮点数(双精度数),它们也可以是整数。

您似乎指定了varType&gt; 1(表示字符串变量),但是'值标签'值是int(表示数值变量)。解决方法是使两者保持一致。上面已经说明了一种方法,另一种方法是将有问题的变量的varType设置为零。

也就是说,这个段落错误很难看。我把它放在我的待办事项列表中,为所有setter函数指定argtype属性(参见https://docs.python.org/2/library/ctypes.html上的15.17.1.6),这样你就会得到一个很好的,可理解的ArgumentError而不是这个令人讨厌的段错误

如果问题仍然存在,请您在https://bitbucket.org/fomcl/savreaderwriter/issues?status=new&status=open打开一个问题,请以最小的例子。

@ekhumoro:savReaderWriter尚未针对Python 2.6或更早版本进行过测试(如果有效,我会感到惊讶),所以dict理解应该没问题。

<强>更新: @ RLS:不客气。也谢谢你,它激励我纠正这个。从提交5c11704开始,现在抛出一个ctypes.ArgumentError(参见https://bitbucket.org/fomcl/savreaderwriter)。下面是一个我也可以用来编写单元测试的例子(Python 3需要b“前缀):

import savReaderWriter as rw, tempfile, os, pprint

savFileName = os.path.join(tempfile.gettempdir(), "some_file.sav")
varNames = [b"a_string", b"a_numeric"]
varTypes = {b"a_string": 1, b"a_numeric": 0}
records = [[b"x", 1], [b"y", 777], [b"z", 10 ** 6]]

# Incorrect, but now raises ctypes.ArgumentError:
valueLabels = {b"a_numeric": {b"1": b"male", b"2": b"female"},
               b"a_string": {1: b"male", 2: b"female"}}

# Correct
#valueLabels = {b"a_numeric": {1: b"male", 2: b"female"},
#               b"a_string": {b"1": b"male", b"2": b"female"}}

kwargs = dict(savFileName=savFileName, varNames=varNames, 
              varTypes=varTypes, valueLabels=valueLabels)
with rw.SavWriter(**kwargs) as writer:
    writer.writerows(records)

# Check if the valueLabels look all right
with rw.SavHeaderReader(savFileName) as header:
    metadata = header.dataDictionary(True)
    pprint.pprint(metadata.valueLabels)