Python: Downcast датафрейм как можно быстрее - PullRequest
0 голосов
/ 11 июля 2019

Привет, я хочу безопасно уменьшить размеры данных на фрейме данных как можно меньше и быстрее. Фрейм данных может иметь любые комбинации смешанных dtypes в столбце, в основном это строковые столбцы с np.nan или строкой 'NaN's. Целочисленные столбцы с nans преобразуются в pandas 24.2, тип данных 'Int8', 'Int16' ... Кажется, что пустые списки и пустые словари приводят к сбоям при преобразовании и понижении частоты, поскольку они преобразуются в числа с плавающей точкой (почему ??), поэтому я исключил их. Мой метод работает, но я не могу поверить, что нет другого простого способа сделать это, тем более нет более быстрого решения. Я долго об этом думаю, и мне нужен быстрый метод, потому что я работаю с кадрами данных, которые могут иметь размер 1000000x150 ячеек.

Мой метод:

def convertAndDowncast(column,downcast=True):
    try:
        column = pd.to_numeric(column, downcast='float',errors='ignore')
        if downcast==True:
            column = pd.to_numeric(column, downcast='integer',errors='ignore')
            if column.dtype == 'int8':
                column = column.astype('Int8',casting='safe')
            elif column.dtype == 'int16':
                column = column.astype('Int16',casting='safe')
            elif column.dtype == 'int32' or column.dtype == 'int64':
                column = column.astype('Int32',casting='safe')
    except Exception as e:
        print(e)
        return column
    finally:
        return column


def dtypeCorrection(df,downcast=True):
    if isinstance(df,pd.DataFrame): 
        maskOfNans = df.isnull().values
        array = df.values
        excludedColumns = set(df.columns[(df.applymap(type) == list).any(0)]) | set(df.columns[(df.applymap(type) == dict).any(0)])
        maskOfStringNans = ((((array=='nan')|(array == 'NaN'))|(array =='NaT'))|(array == 'None'))
        combinedMasks = maskOfNans|maskOfStringNans
        array[combinedMasks] = 0
        df[df.columns] = array
        for column in df[set(df)-excludedColumns]:
            df[column] = convertAndDowncast(df[column],downcast=downcast)
        df = df.mask(combinedMasks, np.nan)
    return df

Тест:

df = pd.DataFrame.from_dict({0:{'integerColumn':1,'strColumn':'test0','floatColumn':0.1,'strIntegerColumn':'0','strFloatColumn':'0.1',
                                'strObjectColumn':'[1,2,3]','objectColumn':[1,2,3],'strIntegerColumn2':'1','strFloatColumn2':'0.2',
                                'testColumn':{},'testColumn2':[],'testColumn3':[1,2,3]},
                            1:{'integerColumn':np.nan,'strColumn':'test1','floatColumn':np.nan,'strIntegerColumn':'NaN','strFloatColumn':'nan',
                               'strObjectColumn':'NaN','objectColumn':np.nan,'strIntegerColumn2':np.nan,'strFloatColumn2':np.nan,
                               'testColumn':{},'testColumn2':[],'testColumn3':[1,2,3]}},orient='index')

dtypeCorrection(df,downcast=True)

Вывод dtypes:

testColumn3           object
integerColumn           Int8
strObjectColumn       object
strFloatColumn2      float32
strIntegerColumn        Int8
strIntegerColumn2       Int8
testColumn2           object
testColumn            object
strFloatColumn       float32
objectColumn          object
floatColumn          float32
strColumn             object
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...