我在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
答案 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)