Pandas - указание dtype со смешанными данными столбца с использованием read_csv - PullRequest
2 голосов
/ 12 апреля 2019

Я пытаюсь загрузить несколько довольно больших файлов CSV (всего: около 30 миллионов строк / 7 ГБ). Некоторые из столбцов смешаны ints и floats - я хочу эти столбцы как np.float16.


В идеале параметр dtype, равный read_csv, должен использоваться для повышения эффективности всего процесса импорта. Но выдается ошибка для этих столбцов смешанных данных.

Вот код и соответствующая ошибка:

def import_processing(filepath, cols, null_cols):
    result = pd.read_csv(filepath, header = None, names = cols.keys(), dtype = cols)
    result.drop(null_cols, axis = 1, inplace = True)
    return result

data_cols = { 'feature_0' : np.float32,
              'feature_1' : np.float32,
              'feature_2' : np.uint32,
              'feature_3' : np.uint64,
              'feature_4' : np.uint64,
              'feature_5' : np.float16,
              'feature_6' : np.float16,
              'feature_7' : np.float16,
              'feature_8' : np.float16,
              'feature_9' : np.float16,
              'feature_10' : np.float16,
              'feature_11' : np.float16,
              'feature_12' : np.float16,
              'feature_13' : np.float16,
              'feature_14' : np.float16,
              'feature_15' : np.float16,
              'feature_16' : np.float16,
              'feature_17' : np.float16,
              'feature_18' : np.float16,
              'feature_19' : np.float16,
              'feature_20' : np.float16,
              'feature_21' : np.float16,
              'feature_22' : np.float16,
              'feature_23' : np.float16,
              'feature_24' : np.float16,
              'feature_25' : 'M8[ns]',
              'feature_26' : 'M8[ns]',
              'feature_27' : np.uint64,
              'feature_28' : np.uint32,
              'feature_29' : np.uint64,
              'feature_30' : np.uint32}

files = ['./file_0.csv', './file_1.csv', './file_2.csv']
all_data = [import_processing(f, data_cols, ['feature_0', 'feature_1']) for f in files]

TypeError: Cannot cast array from dtype('O') to dtype('float16') according to the rule 'safe'

Но, если я не использую параметр dtype, скорость импорта значительно замедляется, поскольку все столбцы смешанного типа данных импортируются как dtype('O') вместо np.float16.

Я обошел это, сначала применив pd.to_numeric (не уверен, почему это не выдает ту же ошибку), который преобразует все столбцы в np.float64, а затем использовал astype() преобразование для получения каждого столбец в тип, который я хочу (включая эти столбцы смешанного типа данных в np.float16).

Этот процесс очень медленный, поэтому мне было интересно, есть ли лучший способ сделать это. В настоящее время моя (очень медленная) рабочая функция выглядит так:

def import_processing(filepath, cols, null_cols):
    result = pd.read_csv(filepath, header = None, names = cols.keys())
    result.drop(null_cols, axis = 1, inplace = True)

    for c in null_cols:
        cols.pop(c, None)

    result[result.columns] = result[result.columns].apply(pd.to_numeric, errors='coerce')
    result = result.astype(cols)
    return result

Редактировать: Я читал, что использование Dask (в целом) является гораздо более эффективным методом управления большими наборами данных в Python. Я никогда не работал с ним раньше, и, насколько мне известно, он обрабатывает многие операции, в основном используя вызовы Pandas - поэтому я думаю, что у него будут те же проблемы с типом данных.

1 Ответ

0 голосов
/ 15 апреля 2019

Исходя из ошибки, я предполагаю, что один из ваших столбцов не является строго числовым и что в ваших данных есть какой-то текст, поэтому Панды интерпретируют его как столбец типа объекта. Невозможно заставить эти данные иметь тип float16. Это всего лишь предположение.

...