У меня есть большой файл .out с 100002 строками. Я работаю в VSCode 1.88.0 и у меня установлен Python 3.12.2. Я читаю только два столбца данных в файле: «Время» и «Сумма (cvBot)», но когда я читаю файл данных с помощью pandas, многие записи в средстве просмотра данных имеют значение NaN, хотя их нет в моем исходном файле. (Например, NaN до строки 10000 последовательно, аналогичная проблема сохраняется, когда я указываю индексный столбец). Пример данных, просматриваемых в VSCode, приведен ниже:
Time cvTop cvBot Sum(cvTop) Sum(cvBot) cvCh0 cvCh1 cTop cRoot cBot cvRoot Sum(cvRoot) Sum(cvNEql) TLevel cGWL cRunOff Sum(cRunOff) (cv(i), Sum(cv(i)), i=1,NObs)
[T] [M/L2/T] [M/L2/T] [M/L2] [M/L2] [M/L2] [M/L2] [M/L3] [M/L3] [M/L3] [M/L2/T] [M/L2] [M/L2] [M/L3] [M/L2] [M/L3] [M/L2/T] [M/L2]
0.0010 0.00000E+00 -0.15405E-02 0.00000E+00 -0.15405E-05 0.00000E+00 0.00000E+00 0.29945E+03 0.00000E+00 0.15410E+04 0.00000E+00 0.00000E+00 0.00000E+00 1 0.00000E+00 0.00000E+00 0.00000E+00 0.29385E+03 0.29385E+00 -0.54338E+04 -0.54338E+01 -0.16439E+05 -0.16439E+02 -0.64983E+04 -0.64983E+01
0.0020 0.00000E+00 0.43077E-02 0.00000E+00 0.27673E-05 0.00000E+00 0.00000E+00 0.30023E+03 0.00000E+00 0.15410E+04 0.00000E+00 0.00000E+00 0.00000E+00 2 0.00000E+00 0.00000E+00 0.00000E+00 0.29437E+03 0.58822E+00 -0.43086E+04 -0.97424E+01 -0.93670E+04 -0.25806E+02 -0.70594E+04 -0.13558E+02
0.0030 0.00000E+00 0.43077E-02 0.00000E+00 0.70750E-05 0.00000E+00 0.00000E+00 0.30070E+03 0.00000E+00 0.15410E+04 0.00000E+00 0.00000E+00 0.00000E+00 3 0.00000E+00 0.00000E+00 0.00000E+00 0.29460E+03 0.88282E+00 -0.37590E+04 -0.13501E+02 -0.70042E+04 -0.32811E+02 -0.68129E+04 -0.20371E+02
.
.
.
2.8186 0.00000E+00 -0.71450E-02 0.00000E+00 0.43578E-03 0.00000E+00 0.00000E+00 0.21151E+07 0.00000E+00 0.15397E+04 0.00000E+00 0.00000E+00 0.00000E+00 998 0.00000E+00 0.00000E+00 0.00000E+00 0.18807E+07 0.41397E+06 -0.24422E+04 -0.70533E+03 0.91943E+02 -0.62800E+02 0.25422E+02 -0.37256E+03
2.8193 0.00000E+00 -0.71450E-02 0.00000E+00 0.43083E-03 0.00000E+00 0.00000E+00 0.21229E+07 0.00000E+00 0.15397E+04 0.00000E+00 0.00000E+00 0.00000E+00 999 0.00000E+00 0.00000E+00 0.00000E+00 0.18877E+07 0.41528E+06 -0.24486E+04 -0.70702E+03 0.91960E+02 -0.62737E+02 0.25429E+02 -0.37255E+03
2.8200 0.00000E+00 -0.71450E-02 0.00000E+00 0.42588E-03 0.00000E+00 0.00000E+00 0.21307E+07 0.00000E+00 0.15397E+04 0.00000E+00 0.00000E+00 0.00000E+00 1000 0.00000E+00 0.00000E+00 0.00000E+00 0.18946E+07 0.41660E+06 -0.24551E+04 -0.70872E+03 0.91977E+02 -0.62673E+02 0.25435E+02 -0.37253E+03
Вот ссылка на файл данных, если кому интересно: Данные
Изображение моего средства просмотра данных VSCode находится здесь, так как я не могу скопировать и вставить выходные данные. Данные
Я намерен прочитать два столбца данных, чтобы построить временной ряд. Текущий код для чтения и построения данных:
import matplotlib.pyplot as plt
import pandas as pd
# Load time series data from a file
file_path = r'C:\Program Files\Hydrus-1D\Examples\Direct\Attempt10\solute1_Copy.out'
data = pd.read_csv(file_path, usecols=["Time", "Sum(cvBot)"], index_col=False, skiprows=[1], sep = " ")
Я также использовал один из столбцов («TLevel») в качестве индексного столбца, но строки данных записываются как NaN до строки 15370.
Я просмотрел страницы, посвященные подобным проблемам, например Pandas read_csv не читает все строки в файле, и мне не удалось заставить его работать. Я не уверен, в чем проблема, но есть дополнительные столбцы данных, которые могут иметь или не иметь метку в крайнем правом столбце моего набора данных, что может быть причиной. Могу ли я как-нибудь заставить панд правильно читать мой файл данных?
Спасибо за ответ. Я очень надеюсь, что это не так, но я попробую.
Итак, я заменил свои данные в файле случайными данными и запустил с ними скрипт, и значения NaN отображаются в записях времени и суммы (cvBot). Так что это проблема с файлом. Не похоже, что есть разрыв или отсутствующее поле.
так у вас не было проблем со случайными данными?
Нет, даже случайные данные создают аналогичную проблему.
Интересный. Можно ли будет предоставить файл? Если он содержит информацию, которой не следует делиться, заполните все случайными данными.
Кстати, причина, по которой я исключаю проблемы с количеством строк, заключается в том, что pd.read_csvпо умолчанию принимает все строки
Привет, Тино, я предоставил файл данных в своем посте. Спасибо за разъяснение по поводу проблемы с количеством строк.
Ваш файл нуждается в небольшой очистке. В начале много пробелов, которые мешают импорту. Я даже попробовал это в Excel и увидел в этом проблему. Я буду работать над сценарием, который читает файл как текст и соответствующим образом анализирует его.
В данных 18 столбцов, но сами данные состоят из 25 чисел. Это правда?
Да все верно. Не уверен, что это поможет, но эти данные являются результатом программной модели Hydrus1D. Честно говоря, я не уверен, что представляют собой столбцы между 18 и 25, поскольку данные, которые меня интересуют, находятся только в первых нескольких столбцы.
Достаточно хорошо, просто хотел заранее уточнить у вас, я назначу номер столбца для этих столбцов...
Кажется, у тебя уже есть хороший ответ





Ваш файл необходимо привести в порядок, прежде чем панды смогут его правильно прочитать. Пробелы используются случайным и непоследовательным образом, поэтому их просто нужно очистить. Следующий код удаляет все начальные и конечные пробелы и преобразует противоречивые пробелы между столбцами в один пробел:
import matplotlib.pyplot as plt
import pandas as pd
import re
import io
# Load time series data from a file
file_path = r'C:\Program Files\Hydrus-1D\Examples\Direct\Attempt10\solute1_Copy.out'
with open(file_path) as f:
lines = f.readlines()
lines = [line.strip() for line in lines]
file_contents = '\n'.join(lines)
file_contents = re.sub(' +', ' ', file_contents)
data = pd.read_csv(io.StringIO(file_contents), usecols=["Time", "Sum(cvBot)"], index_col=False, skiprows=[1], sep = " ")
Шаг очистки можно упростить до двух строк, если вы хотите сделать его более кратким:
with open(file_path) as f:
file_contents = re.sub(' +', ' ', '\n'.join([line.strip() for line in f.readlines()]))
Обратите внимание на вызов io.StringIO(), поскольку он преобразует строку в файл, подобный объекту, который панды используют для чтения.
Это должно позволить пандам правильно считывать данные, но учтите, что вам может потребоваться указать типы ожидаемых данных в зависимости от вашего варианта использования.
Последняя строка заголовка содержит следующее:
(cv(i), Sum(cv(i)), i=1,NObs)
Я не уверен, сколько столбцов они представляют. Это 1 или 4 столбца?
Вы также использовали пробел (" ") для разделения столбцов данных. Некоторые столбцы разделены 1 пробелом, другие — 2 пробелами. Вместо этого лучше использовать \s+.
df = pd.read_csv(
"solute1_Copy.out",
skiprows=2, # skip the first 2 rows
header=None, # the data now have no header
sep = "\s+", # one or multiple spaces separate the columns
usecols=[0, 3], # use the columns at index 0 and 3
names=["Time", "Sum(cvBot)"], # manually assign a name to them
skipfooter=1, # skip the last row
engine = "python" # to avoid a warning
)
сохранил на потом, отличный ответ!
Мне потребовалось некоторое время, чтобы вернуться, но я попробовал ваше решение, и оно работает. Спасибо, что написали и ясно объяснили!
Единственная проблема, с которой вы столкнулись (ИМХО), заключается в том, что у вас есть записи фиксированной длины и вы пытаетесь обращаться с ними так, как если бы они были записями с разделителями. Используйте read_fwf(), чтобы прочитать строки как данные фиксированной длины.
import pandas
file_name = "solute1_Copy.out"
fwidths = [(0, 14), (54, 67)]
df = pandas.read_fwf(file_name, colspecs=fwidths, index_col=False, skiprows=[1], skipfooter=1, dtype=float)
print(df)
Даю вам:
Time Sum(cvBot)
0 0.0010 -0.000002
1 0.0020 0.000003
2 0.0030 0.000007
3 0.0030 0.000007
4 0.0031 0.000007
... ... ...
99996 4013.0000 -55104.000000
99997 4014.0000 -55104.000000
99998 4015.0000 -55104.000000
99999 4016.0000 -55104.000000
100000 4017.0000 -55104.000000
Спасибо, мне потребовалось время, чтобы попробовать это решение, потому что я перестал использовать MATLAB для решения этих проблем. У меня это отлично работает!
Я думаю, что-то не так с вашим файлом. Попробуйте заменить все данные в файле случайными данными и импортировать еще раз. Если это работает, вам следует проверить, что находится в исходном файле, нет ли каких-либо разрывов или отсутствующих полей.