通过为每一列使用缩放数据来减少Pandas DataFrame的内存消耗?

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

我想在管理某些熊猫DataFrame时减少内存消耗。我知道例如从float64切换到flot32的技巧,这很有趣。

要走得更远,并且知道我的数值实际上具有最小的绝对最小值和最大值,我想知道是否无法要求熊猫对给定的列使用比例因子?

最好的例子可以是百分比。

使用百分比,您知道最小值为0,最大值为1。这些最小值和最大值可以存储为列的属性。

然后我可以使用int16,并且列值将被存储为[-128之间的缩放值; 127]。然后,当使用它们时,将使用已存储为列属性的最小值和最大值将它们缩放回其“原始值”(经过四舍五入)。

这种方法是否可以用于管理熊猫数据框?

感谢您的帮助和反馈!最好,

python pandas memory-management
1个回答
0
投票

我使用此有用的帮助器功能。但是当然可以使用更好的解决方案。

def reduce_mem_usage(data_frame):
start_mem_usg = data_frame.memory_usage(deep=True).sum() / 1024 ** 2
print("Memory usage of the dataframe is : {:03.2f} {}".format(start_mem_usg, " MB"))
for col in data_frame.columns:
    if data_frame[col].dtype not in [object, "datetime64", "datetime64[ns]"]:  # Exclude strings

        print("******************************")
        print("Column: ", col)
        print("dtype before: ", data_frame[col].dtype)
        is_int = False
        try:
            mx = data_frame[col].max()
        except Exception:
            continue
        mn = data_frame[col].min()
        try:
            as_int = data_frame[col].fillna(0).astype(numpy.int64)
            result = (data_frame[col] - as_int)
            result = result.sum()
            if result > -0.01 and result < 0.01:
                is_int = True
        except:
            continue

        try:

            if is_int:
                if mn >= 0:
                    if mx < 255:
                        data_frame[col] = data_frame[col].astype(numpy.uint8)
                    elif mx < 65535:
                        data_frame[col] = data_frame[col].astype(numpy.uint16)
                    elif mx < 4294967295:
                        data_frame[col] = data_frame[col].astype(numpy.uint32)
                    else:
                        data_frame[col] = data_frame[col].astype(numpy.uint64)
                else:
                    if mn > numpy.iinfo(numpy.int8).min and mx < numpy.iinfo(numpy.int8).max:
                        data_frame[col] = data_frame[col].astype(numpy.int8)
                    elif mn > numpy.iinfo(numpy.int16).min and mx < numpy.iinfo(numpy.int16).max:
                        data_frame[col] = data_frame[col].astype(numpy.int16)
                    elif mn > numpy.iinfo(numpy.int32).min and mx < numpy.iinfo(numpy.int32).max:
                        data_frame[col] = data_frame[col].astype(numpy.int32)
                    elif mn > numpy.iinfo(numpy.int64).min and mx < numpy.iinfo(numpy.int64).max:
                        data_frame[col] = data_frame[col].astype(numpy.int64)

                        # Make float datatypes 32 bit
            else:
                data_frame[col] = data_frame[col].astype(numpy.float32)
            print("dtype after: ", data_frame[col].dtype)
            print("******************************")
        except ValueError:
            continue
print("___MEMORY USAGE AFTER COMPLETION:___")
mem_usg = data_frame.memory_usage(deep=True).sum() / 1024 ** 2
print("Memory usage is: {:03.2f} {}".format(mem_usg, " MB"))
print("This is ", 100 * mem_usg / start_mem_usg, "% of the initial size")
return data_frame
© www.soinside.com 2019 - 2024. All rights reserved.