- Урок 5. Логический тип данных
- Описание данных логического типа
- Логические операции
- Стандартные логические функции
- задачи для самостоятельного решения
- Считываем числовые данные из файла на Python
- Введение
- Способы чтения данных из файла
- Способ 1 — построчное считывание с преобразованием
- Способ 2 — преобразование при помощи map
- Способ 3 — с использованием регулярного выражения
- Способ 4 — с использованием CSV Reader
- Способ 5 — Numpy loadtxt
- Способ 6 — Numpy genfromtxt
- Способ 7 — Pandas read_csv
- Методы тестирования скорости чтения
- Сравнение с компилируемыми языками программирования
- Fortran
- C++
- Результаты тестирования
- Итог
- 10 commentaries to post
Урок 5. Логический тип данных
На этом уроке мы остановимся на логическом или булевском типе данных.
Этот тип данных представлен двумя значениями: true — истина и false — ложь. Для описания величин логического типа используется зарезервированное слово boolean. Для размещения в памяти переменной логического типа требуется 1 байт.
Логические выражения широко используются в условных операторах и операторах цикла для определения пути продолжения алгоритма.
Описание данных логического типа
Идентификатор типа
Допустимые значения
Размер выделяемой памяти
Пример описания величин логического типа:
Свои значения переменные логического типа получают обычно в результате выполнения операции сравнения (отношения): »» (больше), »=» (больше или равно), »<>» (не равно), »=» (равно).
Результат отношения равен TRUE, если отношение удовлетворяется для значений входящих в него операндов, а FALSE в противном случае. Простые условия, содержащие операции сравнения, можно соединить логическими связками (логическими операциями) и получить сложное условие или логическое выражение.
Логические операции
В языке программирования Паскаль для работы с логическими операндами введены следующие логические операции:
- not — отрицание (инверсия);
- and — конъюнкция (логическое умножение);
- or — дизъюнкция (логическое сложение, объединение);
- xor — исключающее или.
Результат работы операций задается следующей таблицей истинности (таблицей значений):
Значение операнда | Значение операции | ||||
a | b | not a | a and b | a or b | a xor b |
false | false | true | false | false | false |
false | true | true | false | true | true |
true | false | false | false | true | true |
true | true | false | true | false | false |
Запомнить эту таблицу очень просто. Операция отрицание меняет значение операнда на противоположное.
Для того, чтобы результат операции логического умножения был истинен, все операнды должны быть истинны.
Для того чтобы логическое сложение дало истину, нужно, чтобы хотя бы один операнд был истинен.
Исключающее или дает истину, только если операнды имеют разные значения. Иногда эту операцию называют выбором альтернативы.
Логические операции, операции отношения и арифметические операции часто встречаются в одном выражении. Причем отношения, стоящие слева и справа от знака логической операции, должны быть заключены в скобки, поскольку логические операции имеют более высокий приоритет.
Вообще, в логическом выражении принят следующий приоритет операций:
Порядок выполнения операций можно изменить скобками. Например, в логическом выражении A OR B AND NOT(A OR B) сначала выполняется заключенная в скобки операция OR, а затем операции NOT, AND, OR.
Стандартные логические функции
- odd(x) = true , если x нечетный ( x целый тип);
- eoln(x) = true , если встретился конец строки текстового файла x ;
- eof(x) = true , если встретился конец файла x .
В остальных случаях эти функции принимают значение false.
В языке Паскаль нет возможности ввода логических данных с помощью оператора read. Однако предусмотрен вывод значений переменных логического типа с помощью оператора write. В этом случае для идентификаторов FALSE и TRUE автоматически отводятся по 6 позиций: две — перед словом TRUE и одна — перед FALSE.
задачи для самостоятельного решения
- Определить значение логического выражения:(-3>=5) Or Not(7 <9) And(0<3)
- Чему равны значения переменных a и b после выполнения последовательности действий:
a := 15 Div (16 Mod 7); b := 34 Mod a *5 — 29 Mod 5*2;
a := 4 * 5 Div 3 Mod 2; b :=4 * 5 Div ( 3 Mod 2);
a := a*b; b:= b*b.
На этом уроке мы рассмотрели логический или булевский тип данных, который используется в условных операторах (if и case ), а также в операторах цикла.
На следующем уроке вы познакомитесь с условным оператором языка Паскаль.
Считываем числовые данные из файла на Python
В данной статье речь пойдет о простой на первой взгляд задаче — считывании числовых данных из текстовых файлов на Python. В сети можно найти десятки способов решения этой задачи, однако эти алгоритмы оказываются малоэффективными при работе с большим объемом данных. В данной статье будут разобраны самые популярные методики, а также произведено сравнение их скорости работы.
Введение
Когда я только начинал изучать Python, главным помощником в работе для меня, как наверное и для большинства программистов, был Stack Overflow. Я почерпнул оттуда много полезной информации, в том числе и о работе с файлами. Однако даже такая тривиальная задача, как оказалось, имеет несколько различных решений, отличающихся друг от друга простотой реализации и скоростью работы.
Большинство предложенных методов предполагают чтение файла построчно с дальнейшим разбиением на блоки и их преобразованием из строкового типа в числовой, поскольку Python в отличии от C/C++ работает с файлами как с массивом строк. Выполнить последовательное чтение данных в массив без преобразования типов, как это можно сделать в C/C++, стандартными средствами языка невозможно (насколько мне известно), и это существенно увеличивает время работы программы при обработке больших объемов данных.
Способы чтения данных из файла
Как уже было сказано выше, файлы в Python представляют собой массив строк, поэтому все найденные методы можно символически поделить на два типа в зависимости от используемого подхода:
- построчное считывание с разбиением и преобразованием типов
- использование библиотек, которые средствами других языков (например, C/C++) считывают файл и передают полученные данные интерпретатору Python
Ниже представлена подборка самых популярных методов чтения числовых данных на Python, отмеченных сообществом Stack Overflow как «best answer».
Способ 1 — построчное считывание с преобразованием
Самый популярный и простой вариант. Заключается в построчном чтении с разбиением полученной строки на блоки, которые затем преобразуются к необходимому типу данных (в данном случае float) и добавляются к заранее созданному списку.
data = [] with open("data.txt") as f: for line in f: data.append([float(x) for x in line.split()])
Способ 2 — преобразование при помощи map
Способ аналогичен предыдущему, за исключением того, что преобразованием данных из строкового формата в числовой занимается функция map.
file = open("data.txt", "r") data = [map(float, line.split("\t")) for line in file]
Способ 3 — с использованием регулярного выражения
Данный способ можно назвать стрельбой из пушки по воробьям, однако у него все же есть свои плюсы: если данные в файле расположены хаотично и отсутствует постоянная структура, то функции split невозможно задать конкретный разделитель и для решения задачи можно использовать регулярное выражение, которое найдет в строке все числа, несмотря на их расположение и наличие разделителей.
import re file = open("data.txt") values = file.read().split("\n") data = [] for key in values: value = re.findall(r"[-+]?\d*\.\d+|\d+", key) if value != []: data.append(value)
Способ 4 — с использованием CSV Reader
Если данные записаны в виде матрицы с постоянными разделителями, то выполнить их чтение можно при помощи модуля CSV Reader, указав в качестве параметра значение разделителя.
import csv with open("data.txt") as f: data = [map(float, row) for row in csv.reader(f, delimiter='\t')]
Способ 5 — Numpy loadtxt
Библиотека Numpy предоставляет широкий набор модулей и функций для обработки числовых данных, в том числе и для чтения массивов из файлов. Одна из реализаций возможна с помощью функции loadtxt, результат работы которой будет записан в numpy.array.
import numpy as np data = np.loadtxt("data.txt", delimiter='\t', dtype=np.float)
Способ 6 — Numpy genfromtxt
Данный способ не сильно отличается от предыдущего, за исключением того, что genfromtxt предоставляет более широкий набор входных параметров: указание различных типов данных для каждого из столбцов, передача ключей для создания ассоциативного массива и так далее.
import numpy as np data = np.genfromtxt("data.txt", delimiter='\t', dtype=np.float)
Способ 7 — Pandas read_csv
Pandas — мощная библиотека для обработки данных на Python. В данном примере рассматривается только чтение данных, но её возможности этим не ограничены. Метод read_csv предоставляет широкий набор входных параметров, а также показывается высокую скорость работы даже при работе с большими объемами данных.
import pandas as pd data = pd.read_csv("data.txt", sep="\t", header=None)
Методы тестирования скорости чтения
Для тестирования скорости чтения числовых данных были сгенерированы 7 тестовых файлов, содержащих 5 столбцов и 10, 100, 1 000, 10 000, 100 000, 1 000 000 и 10 000 000 строк случайных чисел формата float. Размер самого большого файла составил 742 Мб.
Для измерения времени работы программы использовалась функция time. Существует мнение, что измерять с её помощью время работы некорректно. Однако в данном случае меня интересовало работа с большими объемами данных, когда время работы программы составляло несколько десятков секунд. В таком случае отклонение в полсекунды вносило погрешность менее 1%.
Сравнение с компилируемыми языками программирования
Программы, созданные на компилируемых языках программирования, работают быстрее, чем их аналоги, написанные на интерпретируемых языках. Мне было интересно сравнить скорость чтения каждого метода с Fortran и C++ — самыми популярными языками в научном программировании, с которыми мне также приходится иметь дело в силу специфики моей работы.
Fortran
Несмотря на то, что Fortran считается устаревшим языком, он все еще очень популярен в научном программировании благодаря простоте написания кода, скорости обмена данных и обширном количестве библиотек, созданных за последние полвека.
Например, считать числовую матрицу из файла можно всего за 3 строчки кода при условии корректности входных данных.
real, dimension (5, 1000) :: data open (1, file='data.txt') read(1, *) data
C++
Дискуссии о том, что лучше: Fortran или C++ ведутся уже давно, даже среди авторов EasyCoding этот спор возникал несколько раз, поэтому мне было еще интересней протестировать чтение матриц на данном языке.
ifstream file(«data.txt»); int count = 100000; float** data = new float*[count]; for(int i = 0; i
Результаты тестирования
В ходе эксперимента были протестированы 7 программ на языке Python и по одной на Fortran и C++, код которых представлен выше. Запуск программ осуществлялся на компьютере с Intel Core i5 2.7 GHz и 8 Гб оперативной памяти.
Для запуска программ использовались следующие интерпретаторы и компиляторы:
Для каждой программы проводилась серия испытаний и измерялось время работы, после чего записывался результат в виде среднего арифметического полученных данных. В таблице ниже жирным в каждой строке выделено наименьшее время работы в зависимости от способа чтения и размера входного файла.
Число строк | Способ | ||||||||
---|---|---|---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 | Fortran | C++ | |
10 | 0.048 | 0.048 | 0.045 | 0.044 | 0.173 | 0.216 | 0.479 | 0.005 | 0.005 |
100 | 0.053 | 0.052 | 0.05 | 0.048 | 0.185 | 0.223 | 0.511 | 0.007 | 0.006 |
1 000 | 0.056 | 0.053 | 0.053 | 0.052 | 0.187 | 0.233 | 0.6 | 0.01 | 0.01 |
10 000 | 0.085 | 0.076 | 0.096 | 0.083 | 0.305 | 0.292 | 0.636 | 0.032 | 0.041 |
100 000 | 0.414 | 0.403 | 0.561 | 0.482 | 1.537 | 0.874 | 0.796 | 0.244 | 0.363 |
1 000 000 | 3.835 | 4.502 | 6.086 | 5.276 | 13.607 | 6.754 | 1.763 | 2.584 | 3.662 |
10 000 000 | 47.931 | 156.944 | 137.398 | 144.75 | 162.724 | 85.642 | 13.632 | 25.652 | 36.622 |
Итог
В ходе данного исследования были протестированы 7 самых популярных варианта чтения числовых матриц на языке Python, предложенными пользователями сайта Stack Overflow и отмеченными сообществом как «верный ответ». Как видно из таблицы с результатами, скорость работы программ не сильно отличается при использовании способов 1-4 на небольших объемах данных. Это связано с тем, что интерпретатор не тратит время на инициализацию сторонней библиотеки, как в методах 5-7.
Однако при увеличении объема входных данных лучше всех себя показал метод 7 с использованием библиотеки Pandas, который даже обогнал по скорости чтения данных языки C++ и Fortran.
Также из результатов теста можно видеть, что программа на Fortran справилась с чтением данных быстрей аналога на C++, что еще раз доказывает его превосходство над самым популярным языком программирования в мире.
10 commentaries to post
Наконец, нашел, что искал. Способ 6 — Numpy genfromtxt, который предоставляет более широкий набор входных параметров: указание различных типов данных для каждого из столбцов, передача ключей для создания ассоциативного массива и так далее.
Спасибо. Сэкономили время на поиск единственного, что нужно для моих вычислений по таблице «тексты-слова»…
FILE* f = fopen(«data.txt», «rb») int count = 10000; float** data = new float*[count]; for(int i = 0; i < count; ++i)
Причем не особо кошерная реализация. Но соответствует предоставленному коду.
Кошерная реализация это:
fread(data, sizeof(float) * 5 * count, f);