读取SPSS文件(.使用pyreadstat在内存中保存.zsav)



我一直在开发一个Django应用。我知道有一些不同的阅读SPSS文件。一种方法是使用熊猫。

import pandas as pd
file_path = "./my_spss_file.sav"
df = pd.read_spss(file_path)
另一种方法是使用pyreadstat
import pyreadstat
df, meta = pyreadstat.read_sav('./my_spss_file.sav')

正如您在上面看到的,与pandas不同,使用using pyreadstat我可以获得元信息,例如标签的变量和值。这就是我用的。这个pyreadstat的问题是我不能用它在内存中读取。在从浏览器上传spss文件后,每次我都必须将其上传到一个目录,然后使用pyreadstat模块从那里读取文件。

def upload_file(request):
result = None
# Get the context from the request.
context = RequestContext(request)
if request.is_ajax():
if "POST" == request.method:
global my_df
global _explore
global base_dir
file = request.FILES['file']
file_name = file.name
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
try:
my_df = None
# Determine the type of the file and get the dataframe
if file_name.endswith('.csv'):
my_df = pd.read_csv(file, header=0)
elif file_name.endswith('.xlsx') or file_name.endswith('.xls'):
my_df = pd.read_excel(file, header=0)
elif file_name.endswith('.sav') or file_name.endswith('.zsav'):
handle_uploaded_file(file, str(file))
file_path = os.path.join(base_dir, "upload\") + file_name
my_df = util.read_spss_file(file_path)
def read_spss_file(f_name):
df, meta = pyreadstat.read_sav(f_name, apply_value_formats=True)
return df
def handle_uploaded_file(file, filename):
upload_dir = os.path.join(base_dir, "upload\") #base_dir + 'upload/'
if not os.path.exists(upload_dir):
os.mkdir(upload_dir)
with open(upload_dir + filename, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)

我不想把上传的spss文件写入磁盘。所以,我想知道是否有一种方法来读取内存spss文件使用pyreadstat模块?

很遗憾,目前还不可能。

Pyreadstat依赖于C库Readstat,该库目前绝对需要磁盘上的一个文件。

这个问题已经在这里提出了。

Pandas read_spss也在后台使用pyreadstat,所以这两种方法实际上是相同的。

class TempFile(type(pathlib.Path())):  # type: ignore
def __exit__(self, exc_type, exc_val, exc_tb):
filepath = str(self.absolute())
try:
os.remove(filepath)
except OSError:
logger.error('romve temporary file: %s failed!', filepath)
self._closed = True
buffer = BytesIO()  # the bytes data

with TempFile('/tmp/file.sav') as fp:
try:
fp.write_bytes(io.getvalue())
return read_sav(fp, encoding=encoding)
except xxx:
# do some fallback
pass

这将有助于从内存中读取字节

最新更新