Я использую pandas DF для обработки большого количества данных (500+ столбцов, 30 000+ строк) из моделирования в нашей лаборатории.
Данные читаются из внешнего файла и имеют небольшие значения в следующем формате:

0.12750246E-61           0.12850512E-26           0.36285493E-05           0.25550131E-57

Если значение меньше, чем E-99, файл опускает E и записывает его как: 0.19768978-156
К сожалению, это устаревшее моделирование, поэтому я не могу изменить способ экспорта данных.
Прямо сейчас, когда я читаю df как 'str', и мне приходится переходить по ячейке, чтобы найти, где E нет, и заменить его вручную.
Для больших файлов это очень медленно, и я уверен, что есть способ лучше.

На самом деле я спрашиваю:

  1. Как найти значения вне формата и обнулить их (желательно при чтении данных)?
  2. Какой dtype вы бы использовали, чтобы сохранить максимальную точность?

Код:
Чтение данных и добавление заголовков:

qt_headers = pd.DataFrame.to_numpy(
        pd.read_csv("qt_species_list.txt", delim_whitespace=True, index_col=0,
                    names=["h"]))  # reads the CHEMKIN headers and converts them to a data frame
    qt_headers = np.append(np.array(["TIME", "TEMP"]), qt_headers)  # adds the Time & Temp col
    moles_df = pd.read_csv(f"OUTPUT\\output1.plt", index_col=False, delim_whitespace=True, dtype=str,
                           names=np.arange(0, len(qt_headers)))
    moles_df.columns = qt_headers

Поиск проблемных ячеек:

    for col in moles_df.columns:
        for idx, cell in enumerate(moles_df[col]):
            if "E" not in cell:
                moles_df[col][idx] = "0.00000000E+00"
        moles_df[col] = moles_df[col].astype(dtype=np.float64)

Вещи, которые я пробовал:

  1. разделение на столбцы и использование isin
  2. pd.replace
  3. pd.mask

Благодарность!

0
omer.kal 24 Ноя 2021 в 13:16

1 ответ

Лучший ответ

Перебор всех строк во всех столбцах выполняется довольно медленно.

Попробуйте этот метод (называемый векторизацией):

Отредактировано

for column in moles.df.columns
    moles_df.loc[moles_df[column].str.contains("E") == False, column] = "0.00000000E+00"
0
Rasmus 24 Ноя 2021 в 14:53
Выглядит неплохо, попробую, а как бы обобщить? не всегда -156 это может поменяться. единственная фиксированная вещь - отсутствие E
 – 
omer.kal
24 Ноя 2021 в 14:46
Я отредактировал свой ответ :)
 – 
Rasmus
24 Ноя 2021 в 14:54