pandas 的最小浮点数据类型/最小化变换大小

问题描述 投票:0回答:1

我有一个包含 17000 列和 50000 行整数值(~1 GB)的数据框。 我将数据帧的每一列除以列的总和(例如,标准化数据)。

我需要指定 dtype,因为否则我最终会得到一个 > 11GB 的输出文件(默认 dtype = float64)(!!!)

我尝试将 dtype 减少为 float16(我能为 numpy 找到的最小的 float dtype)甚至 float32。

例如dtype = float32 或 dtype=float16

thisPart.div(thisPart.sum(axis=1), axis=0, dtype=float32)*(10**6)

如果我将 dtype 设置为 float32 或 float16,我得到

NameError: name 'float32' is not defined

如果我将 dytpe 设置为 np.float16 或 np.float32,我得到

 3 TypeError: f() got an unexpected keyword argument 'dtype'

作为参考,我正在运行一个 bash.sh 脚本,该脚本使用 numpy 和 pandas 访问 conda 环境

底线:在不使其大小爆炸的情况下变换该矩阵的最小方法是什么? 除了我现在正在做的事情之外,我也愿意接受其他方法。

pandas dataframe floating-point data-science
1个回答
0
投票

如果您的数据帧密度较低(包含大量零、

np.nan
或其他值),这通常是变量数量较多的情况,您可以将列转换为
Sparse
数据类型,从而大大减少内存使用,有时会加快计算速度(尽管这里的情况似乎并非如此)。

这是一个玩具示例,说明了内存和速度的差异:

import numpy as np
import pandas as pd
import time

# Generate binary dense matrix with low density (~90% are zeros)
df = pd.DataFrame(np.random.randint(low=0, high=50, size=(50_000, 17_000)))
df[df>5] = 0
df[0].value_counts()

# Memory usage ~3.2 GB
print(f"Memory usage:{df.memory_usage(deep=True).sum() / 1024 ** 2:.1f} MB")

# Time elapsed 11 seconds
start = time.time()
df.div(df.sum(axis=1), axis=0,)*(10**6)
print(f"Time elapsed: {time.time() - start:.2f} seconds")

# Convert to sparse dataframe
sdf = df.copy()
sdf = sdf.astype(pd.SparseDtype(dtype='int8', fill_value=0))

# Memory usage ~0.4 GB (8x reduction)
print(f"Memory usage:{sdf.memory_usage(deep=True).sum() / 1024 ** 2:.1f} MB")

# Time elapsed 69 seconds (>6x increase)
start = time.time()
sdf.div(sdf.sum(axis=1), axis=0,)*(10**6)
print(f"Time elapsed: {time.time() - start:.2f} seconds")
© www.soinside.com 2019 - 2024. All rights reserved.