Маринованные струны против Номера рассолов, различные размеры файлов рассолов на жестком диске

#python #dataframe #pickle

Вопрос:

У меня есть два кадра данных. Один со строковыми столбцами, а другой имеет только цифры. Они оба имеют одинаковый размер в памяти, но при мариновании у них разные размеры файлов на жестком диске.

Вот код:

 import pandas as pd
import numpy as np
import pickle
import random
import string
import sys



output_dir = './output/'

max_r = 2000
max_c = 1000

numerical_df = pd.DataFrame(np.random.rand(max_r, max_c))

with open(output_dir   'numerical_df'   '.pkl', 'wb') as fout:
        pickle.dump(numerical_df, fout)

categorical_df = pd.DataFrame()
for j in range(int(max_c/10.8)):
    categorical_df['dummy_object_col' str(j)] = [''.join(random.choices(string.ascii_uppercase   string.digits, k=30))]*max_r

with open(output_dir   'categorical_df'   '.pkl', 'wb') as fout:
        pickle.dump(categorical_df, fout)
        

print('sys.getsizeof '   'numerical_df '   str(sys.getsizeof(numerical_df)/(1024)))
print('memory_usage '   'numerical_df '   str(numerical_df.memory_usage(index=True, deep=True).sum()/(1024)))

print('sys.getsizeof '   'categorical_df '   str(sys.getsizeof(categorical_df)/(1024)))
print('memory_usage '   'categorical_df '   str(categorical_df.memory_usage(index=True, deep=True).sum()/(1024)))  

 

Вот вывод, который показывает, что оба фрейма данных имеют почти одинаковый размер памяти в КБ:

 sys.getsizeof   numerical_df       15625.140625
memory_usage    numerical_df       15625.125
sys.getsizeof   categorical_df     15632.953125
memory_usage    categorical_df     15632.9375
 

Когда я смотрю на замаринованные размеры файлов на жестком диске, они отличаются. Похоже, строки более сжаты, чем числа. Количество используемых символов не уменьшит разницу в размерах файлов. Протестировано с k=1, k=30 и k=60.

 categorical_df.pkl   has  821 KB
numerical_df.pkl     has  15626 KB
 

Когда я изменил код, чтобы использовать случайные строки в каждом столбце, я получаю разные размеры файлов, вот новый фрейм данных:

 categorical_df2 = pd.DataFrame()
for j in range(int(max_c/10.8)):
    random_strs = []
    for i in range(max_r):
        random_strs.append(''.join(random.choices(string.ascii_uppercase   string.digits, k=30)))
    categorical_df2['dummy_object_col' str(j)] = random_strs

 

Вывод:

 sys.getsizeof     numerical_df       15625.140625
memory_usage      numerical_df       15625.125
sys.getsizeof     categorical_df     15632.953125
memory_usage      categorical_df     15632.9375
sys.getsizeof     categorical_df2    15632.953125
memory_usage      categorical_df2    15632.9375
 

Size of pickled files:

 categorical_df.pkl   has  821 KB
categorical_df2.pkl  has  5944 KB
numerical_df.pkl     has  15626 KB
 

The question is why/how pickle lib dumps strings and numbers differently, which resulted in different pickled file sizes.