Давайте предположим, что ваши входные данные - это словарь. Затем вы можете использовать NumPy для векторизованного решения. Сначала вы преобразуете свои входные списки в массив NumPy и используете аргумент axis=1
, чтобы получить RMSE.
# Input data
dicts = {0: [0, 0, 0, 0], 1: [1, 0, 0, 0], 2: [1, 1, 0, 0], 3: [1, 1, 1, 0],4: [1, 1, 1, 1]}
new_value = np.array([0.9539342, 0.84090066, 0.46451256, 0.09715253])
# Convert values to array
values = np.array(list(dicts.values()))
# Compute the RMSE and get the index for the least RMSE
rmse = np.mean((values-new_value)**2, axis=1)**0.5
index = np.argmin(rmse)
print ("The closest value is %s" %(values[index]))
# The closest value is [1 1 0 0]
Я думаю, что функция записей времени выполнения библиотеки FileHelpers могла бы помочь u. http://filehelpers.sourceforge.net/runtime_classes.html
Вы уверены, что файл является "слишком большим"? Вы попробовали его тот путь, и это вызвало проблему?
при выделении большого объема памяти, и Вы не используете его прямо сейчас, Windows просто выгрузит его к диску. Следовательно, путем доступа к нему от "памяти", Вы выполните то, что Вы хотите - произвольный доступ к файлу на диске.
Этот точный вопрос задали в 2006 здесь: http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic40275.aspx
Сводка:
"Проблема состоит в том, что StreamReader буферизует данные, таким образом, значение, возвращенное в BaseStream. Свойство Position всегда перед фактической обработанной строкой".
Однако, "если файл кодируется в текстовом кодировании, которое является фиксированной шириной, Вы могли отслеживать то, сколько текста было прочитано и умножает это на ширину"
, и в противном случае можно просто использовать FileStream и считать символ за один раз и затем BaseStream. Свойство Position должно быть корректно
Пара элементов, которые могут вас заинтересовать.
1) Если строки представляют собой фиксированный набор символов по длине, это не обязательно полезная информация, если набор символов имеет переменные размеры (например, UTF-8). Так что проверьте свой набор символов.
2) Вы можете определить точное положение файлового курсора из StreamReader, используя значение BaseStream.Position IF , вы сначала очистите () буферы (что приведет к тому, что текущая позиция будет там, где следующая чтение начнется - через один байт после последнего прочитанного байта).
3) Если вы заранее знаете, что точная длина каждой записи будет равняться количеству символов, а набор символов использует символы фиксированной ширины (так что каждая строка имеет одинаковое количество байтов), вы можете использовать FileStream с фиксированным размером буфера, соответствующим размеру строки, и позиция курсора в конце каждого чтения будет, по необходимости, началом следующей строки.
4) Есть ли какая-то конкретная причина, по которой, если строки имеют одинаковую длину (предполагая здесь в байтах), вы не просто используете номера строк и не вычисляете байтовое смещение в файле на основе размера строки x номера строки ?
Можно использовать Систему. IO.FileStream вместо StreamReader. Если Вы знаете точно, что содержит файл (кодирование, например), можно сделать всю операцию как с StreamReader.
Действительно ли кодирование является фиксированным размером один (например, ASCII или UCS-2)? Если так, Вы могли отслеживать индекс символа (на основе количества символов, которые Вы видели), и найдите двоичный индекс на основе этого.
Иначе, нет - необходимо было бы в основном записать собственную реализацию StreamReader, которая позволяет Вам посмотреть на двоичный индекс. Это - позор, что StreamReader не реализует это, я соглашаюсь.
Если Вы гибки с тем, как файл данных записан, и не возражайте против него являющийся немного менее благоприятным для текстового редактора, Вы могли записать свои записи с BinaryWriter:
using (BinaryWriter writer =
new BinaryWriter(File.Open("data.txt", FileMode.Create)))
{
writer.Write("one,1,1,1,1");
writer.Write("two,2,2,2,2");
writer.Write("three,3,3,3,3");
}
Затем первоначально чтение каждой записи просто, потому что можно использовать метод ReadString BinaryReader:
using (BinaryReader reader = new BinaryReader(File.OpenRead("data.txt")))
{
string line = null;
long position = reader.BaseStream.Position;
while (reader.PeekChar() > -1)
{
line = reader.ReadString();
//parse the name out of the line here...
Console.WriteLine("{0},{1}", position, line);
position = reader.BaseStream.Position;
}
}
BinaryReader не буферизуется так, Вы заставляете надлежащее положение хранить и использовать позже. Единственная стычка анализирует имя из строки, которая можно иметь отношение к StreamReader так или иначе.
There are some good answers provided, but I couldn't find some source code that would work in my very simplistic case. Here it is, with the hope that it'll save someone else the hour that I spent searching around.
The "very simplistic case" that I refer to is: the text encoding is fixed-width, and the line ending characters are the same throughout the file. This code works well in my case (where I'm parsing a log file, and I sometime have to seek ahead in the file, and then come back. I implemented just enough to do what I needed to do (ex: only one constructor, and only override ReadLine()), so most likely you'll need to add code... but I think it's a reasonable starting point.
public class PositionableStreamReader : StreamReader
{
public PositionableStreamReader(string path)
:base(path)
{}
private int myLineEndingCharacterLength = Environment.NewLine.Length;
public int LineEndingCharacterLength
{
get { return myLineEndingCharacterLength; }
set { myLineEndingCharacterLength = value; }
}
public override string ReadLine()
{
string line = base.ReadLine();
if (null != line)
myStreamPosition += line.Length + myLineEndingCharacterLength;
return line;
}
private long myStreamPosition = 0;
public long Position
{
get { return myStreamPosition; }
set
{
myStreamPosition = value;
this.BaseStream.Position = value;
this.DiscardBufferedData();
}
}
}
Here's an example of how to use the PositionableStreamReader:
PositionableStreamReader sr = new PositionableStreamReader("somepath.txt");
// read some lines
while (something)
sr.ReadLine();
// bookmark the current position
long streamPosition = sr.Position;
// read some lines
while (something)
sr.ReadLine();
// go back to the bookmarked position
sr.Position = streamPosition;
// read some lines
while (something)
sr.ReadLine();