Полное руководство по работе со строковыми данными в Python.

Вступление

В огромном мире науки о данных и компьютерного программирования существует множество различных типов данных, которые необходимо обрабатывать определенным образом. В вычислениях мы очень привыкли часто работать с числами и математикой для достижения целей. Однако, хотя компьютеры могут говорить численно, люди - нет, а данные, содержащие символы или символы, в компьютерном программировании называются строковым типом данных.

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

К счастью, класс Pythonic str на самом деле довольно прост в использовании и может сделать даже самые сложные операции простыми! Большое различие между строками и другими типами данных в программировании состоит в том, что компьютер на самом деле не понимает строку сам по себе. Компьютеры работают с числами, и все строки представлены на высоком уровне без этих чисел, но за кулисами существует множество методов, которые мы можем использовать для преобразования этих строк, чтобы они были более интерпретируемыми компьютером.

"ноутбук"

Класс str

Класс str - это странный способ именования строк в Python, который обеспечивает отличные функциональные возможности, позволяющие легко манипулировать строками. Важно помнить, что сильной стороной языка Python, которым восхищались с первого дня, является его высокоуровневый интерфейс для данных и сценариев. Конечно, чтобы открывать файлы, писать текст и работать с данными, типы данных должны соответствующим образом облегчать работу со строками и вводом-выводом. В результате класс str на самом деле вполне способен управлять символьными данными внутри него. Однако для правильного понимания класса str, вероятно, будет хорошей идеей немного его деконструировать.

Создание струн

Каждый раз, когда мы используем оператор утверждения для данных, Python просматривает свои базовые типы данных, чтобы найти точное соответствие предоставленным данным. Это, конечно, true или строка, которую можно построить так:

string = "Hello, my name is Emmett :)"

Теперь давайте посмотрим на тип этой новой строки:

type(string)

Итерация

Прежде всего, важно отметить, что этот тип на самом деле является итерабельным. Строка - это просто список символов, которые отображаются по порядку, и, как список, мы можем вызывать индексы строки. Это также означает, что мы можем использовать методы, которые принимают итерацию в качестве параметра с объектом str, например, len ():

string[1]
string[0]
len(string)

Это также означает, что мы можем использовать этот объект с обычным циклом for.

for char in string:
    print(char)

Функции

Как и следовало ожидать, класс str также содержит ряд функций, которые можно невероятно эффективно использовать для управления символами, содержащимися в строке. Конечно, на то, чтобы просмотреть их все, уйдет целая вечность, но я покажу те, которые я нашел наиболее полезными! Первой в этом списке идет функция strip (). Эта функция используется для удаления конечных и предшествующих пробелов из строк. Рассмотрим следующую строку:

h = "    This string starts and ends with spaaaace               "

В этой строке много пробелов как до, так и после себя, что может быть очень проблематичным, если мы пытаемся работать с моделью, используя эту строку! Мы можем очень легко и быстро решить эту проблему, используя функцию strip (), чтобы удалить все эти лишние пробелы.

print(h.strip())

Еще одна интересная функция в этом классе - функция replace (). Это используется для замены определенных комбинаций символов другими комбинациями символов. Проверить это:

ex = "I love Data Science"
ex.replace("Data", "Biological")

Набор методов, которые также могут пригодиться для исследования данных строкового типа, - это isalnum () и isalpha () соответственно. Эти две функции могут использоваться для возврата логического значения, которое будет различать, содержит ли строка числа или нет. Есть несколько других, похожих на это, которые можно использовать, чтобы определить, является ли строка на самом деле числом с плавающей запятой или целым числом, но пока давайте посмотрим на использование этих двух:

numbers = “2”
nonumbs = “two”
print(numbers.isalpha())
print(nonumbs.isalpha())
print(numbers.isalnum())
print(nonumbs.isalnum())

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

txt = "I like fish. I like tacos. So I like fish tacos!"
x = txt.rfind("fish")
z = txt.rfind("like")
print(x, z)

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

fish1, fish2, fish3 = txt.partition("I like tacos.")
print(fish1)
print(fish2)
print(fish3)

Используя функцию index (), мы также можем получить индекс любого заданного набора символов. В этом примере я использую это, чтобы распечатать символы рыбы отдельно, получая индекс и длину перед индексированием строки на основе этих двух значений, чтобы получить только строку, которую мы изначально проиндексировали:

searchingfor = "fish"
print(txt.index("fish"))
start = txt.index("fish")
sl = len(searchingfor)
for i in range(start, start + sl):
    print(txt[i])

Записка

Все эти функции, которые мы только что рассмотрели, великолепны и все такое, но как часто мы на самом деле работаем с одной большой строкой в ​​Data Science? Правильный ответ встречается не часто, поэтому важно знать, как мы можем применить эти методы ко всему списку строк, а не только к одной. Для этого мы обычно используем функцию Pandas apply (), которая принимает лямбда-выражение и применяет его ко всей серии или типу фрейма данных.

import pandas as pd
listofstr = ["Hello", "Hi", "Hello", "Hi"]
nums = [5, 10, 15, 20]
df = pd.DataFrame({"A" : listofstr, "B" : nums})
df["A"] = df["A"].apply(lambda x: x.replace("H", "W"))
df.head(5)

Регулярные выражения

Еще одна вещь, которую я хотел бы коснуться в отношении класса str и строк в целом, - это концепция регулярных выражений. Регулярные выражения - это вызовы контекста для вашего компилятора, которые позволяют программисту расширить функциональность строки. При этом они в некоторой степени необходимы для прочной основы программирования со строками, но в качестве примера я продемонстрирую \ n. \ n - регулярное выражение, которое используется для создания новой строки. Существует множество регулярных выражений, которые можно поместить в строки, чтобы изменить их поведение, и это, конечно, лишь верхушка айсберга, когда дело доходит до работы со строкой.

poem = """I tried a career called data science,\n Then befriended a colony of ants\n
The ants ate my sugar,\n
so i took my cooler,\n
and flooded, so harshly, their pants"""
print(poem)

Кодирование

Строки - отличная форма данных, но с компьютерной точки зрения они действительно не имеют смысла для компьютеров. Компьютеры интерпретируют символы и текст как произвольные числа с плавающей запятой, которые используются для их представления в Юникоде или ANSI. Поскольку эти символы совершенно произвольны для компьютера и субъективны для нас, чтобы фактически использовать эти данные для чего-то вроде машинного обучения или даже статистики - нам нужно будет их закодировать. Кодирование - отличный способ перевести произвольные символы в реальные данные, которые ничего не значат. Существует множество типов кодировщиков, но три основных из них - это LabelEncoders, OrdinalEncoders и Onehotencoders.

Onehotencoding расширяет размерность строки, делая каждую отдельную категорию функцией типа bool. Это может быть как положительным, так и отрицательным в зависимости от приложения, потому что иногда эта более высокая размерность может привести к серьезным проблемам, но иногда может быть невероятно полезной. Это особенно верно, если ваша функция представляет собой небольшое подмножество классов, где компромиссы размеров не будут ощущаться почти так же при небольшом количестве измерений. Для этой цели мы можем использовать Onehotencoder, входящий в состав Sklearn:

from sklearn.preprocessing import OneHotEncoder

Теперь давайте создадим DataFrame с некоторыми строками на основе классов:

df = pd.DataFrame({"Danger_Level": ["A", "A", "C", "D", "C", "A", "B"],
                   "Layer_Count": [5, 6, 12, 19, 13, 6, 9]})

Теперь инициализируем наш кодировщик, вызвав конструктор без параметров:

encoder = OneHotEncoder()

Затем нам нужно изменить форму нашей единственной функции. Это потому, что SkLearn предпочитает, чтобы мы работали с матрицами, а не с одномерными массивами в фреймах данных. Обычно в матрице объекты перечислены с наблюдениями, идущими по вертикали, а не по горизонтали. В результате наша функция будет выглядеть как набор различных функций с одним образцом для каждой, что не так. Чтобы исправить это, нам нужно будет преобразовать это в массив NumPy, а затем изменить его форму:

import numpy as np
dl = np.array(df["Danger_Level"]).reshape(-1, 1)

Теперь мы можем вызвать метод fit_transform () в нашем кодировщике, чтобы закодировать наш новый массив dl NumPy:

output = encoder.fit_transform(dl)

То же самое можно сделать и с OrdinalEncoder. OrdinalEncoder отличается от кодировщика OneHot тем, что сохраняет размерность нашей функции. Кодировщик просто сопоставляет классы с целочисленными значениями, а затем заменяет эти значения в данных всякий раз, когда они совпадают:

from sklearn.preprocessing import OrdinalEncoder
encoder = OrdinalEncoder()
encoder.fit_transform(dl)

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

from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
encoder.fit_transform(dl)

Заключение

Строки могут быть интересным типом данных из-за их субъективного восприятия людьми, которого нет для компьютеров, но независимо от этого они, безусловно, очень важны для многих данных, с которыми регулярно работают специалисты по данным. К счастью, Python имеет невероятно прочную основу для работы с этими типами данных, и знание правильных методов в этом отношении может сэкономить много времени! Большое спасибо за чтение и удачи со струнами!