我有一个非常大的 SAS 文件,无法容纳在我的服务器内存中。我只需要转换为镶木地板格式的文件。为此,我使用 pandas 中
chunksize
方法的
read_sas
选项分块读取它。它主要是在工作/做它的工作。除此之外,一段时间后它会失败并出现以下错误。
此特定 SAS 文件有 79422642 行数据。目前尚不清楚为什么它在中间失败。
import pandas as pd
filename = 'mysasfile.sas7bdat'
SAS_CHUNK_SIZE = 2000000
sas_chunks = pd.read_sas(filename, chunksize = SAS_CHUNK_SIZE, iterator = True)
for sasDf in sas_chunks:
print(sasDf.shape)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
(2000000, 184)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/anaconda3/lib/python3.10/site-packages/pandas/io/sas/sas7bdat.py", line 340, in __next__
da = self.read(nrows=self.chunksize or 1)
File "/opt/anaconda3/lib/python3.10/site-packages/pandas/io/sas/sas7bdat.py", line 742, in read
rslt = self._chunk_to_dataframe()
File "/opt/anaconda3/lib/python3.10/site-packages/pandas/io/sas/sas7bdat.py", line 795, in _chunk_to_dataframe
rslt[name] = pd.Series(self._string_chunk[js, :], index=ix)
File "/opt/anaconda3/lib/python3.10/site-packages/pandas/core/series.py", line 461, in __init__
com.require_length_match(data, index)
File "/opt/anaconda3/lib/python3.10/site-packages/pandas/core/common.py", line 571, in require_length_match
raise ValueError(
ValueError: Length of values (2000000) does not match length of index (1179974)
我刚刚使用较小的块大小在行数较少的较小 SAS 文件上测试了相同的代码逻辑,如下所示,它似乎工作正常,没有任何错误,并且还处理小于块大小参数的最后剩余块:
filename = 'mysmallersasfile.sas7bdat'
SAS_CHUNK_SIZE = 1000
sas_chunks = pd.read_sas(filename, chunksize = SAS_CHUNK_SIZE, iterator = True)
for sasDf in sas_chunks:
print(sasDf.shape)
(1000, 5)
(1000, 5)
(1000, 5)
(1000, 5)
(983, 5)
这个错误信息“ValueError: Length of values (2000000) does not match length of index (1179974)”表明,当创建 Pandas DataFrame 时,出现了不一致的情况。代码试图用 2,000,000 个新值创建一个 DataFrame 列,但索引只有 1,179,974 个条目。
虽然不是立即明显的,但基于在大型 SAS 文件中循环的次数(20 次迭代),问题似乎出在 SAS 文件中包含缺失值的行 。Pandas 可能以不同的方式处理这些缺失值,导致索引和数据值的长度不匹配。
以下是一些解决此问题的步骤:
-
处理缺失值:
使用
na_values
或keep_default_na
参数在read_sas
函数中处理缺失值。这将确保 Pandas 在读取数据时一致地处理缺失值。
python
sas_chunks = pd.read_sas(filename, chunksize=SAS_CHUNK_SIZE, iterator=True, na_values=['.', 'NA'])
- 验证数据完整性: 检查每个块中的行数,以确保读取的数据与预期一致。
python
total_rows = 0
for i, sasDf in enumerate(sas_chunks):
print(f"Chunk {i+1}: {sasDf.shape[0]} rows")
total_rows += sasDf.shape[0]
print(f"Total rows read: {total_rows}")
- 逐步调试: 如果问题仍然存在,请尝试使用较小的块大小或逐步调试代码,以确定导致错误的特定块或列。
通过在读取数据时显式处理缺失值并验证数据完整性,可以解决此错误并确保的代码在处理大型 SAS 文件时可靠地工作。
此外,考虑以下因素:
-
Pandas 和
read_sas
的版本: 确保使用的是最新版本的 Pandas,因为它可能包含对read_sas
功能的错误修复或改进。 - SAS 文件结构: 复杂的 SAS 文件结构或数据类型可能会导致问题。如果可能,请尝试简化文件结构或将其转换为更标准的格式。
通过遵循这些步骤,应该能够解决问题并成功地将大型 SAS 文件转换为 Parquet 格式。
标签:python,pandas,sas From: 78757169