DevGang
Авторизоваться

Списки, кортежи, словари и фреймы данных в Python: полное руководство

Все, что вам нужно знать, чтобы освоить наиболее часто используемые структуры данных в Python

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

Python имеет множество структур данных, которые позволяют нам хранить данные. В этой статье мы рассмотрим наиболее часто используемые из них. Итак, если вы только начинаете свою карьеру и вам нужно изучить структуры данных, то эта статья определенно для вас.

Вот что вы найдете здесь:

Оглавление:

Списки
   Определения и примеры создания
   Манипуляции со списками
   Понимание списка
   Список списков
Кортежи
Словари
   Работа со словарями
   Вложенные словари
   Понимание словаря
Фреймы данных
    Базовые манипуляции с фреймами данных с помощью Pandas

Списки

Определения и примеры создания

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

Для создания списка элементы должны быть заключены в квадратные скобки и разделены запятой. Например, вот как мы можем создать список целых чисел:

# Create list of integers
my_integers = [1, 2, 3, 4, 5, 6]

Но в списках также могут храниться «смешанные» типы. Например, давайте создадим список как с целыми числами, так и со строками:

# Create a mixed list
mixed_list = [1, 3, "dad", 101, "apple"]

Чтобы создать список, мы также можем использовать встроенную функцию Python list(). Вот как мы можем его использовать:

# Create list and print it
my_list = list((1, 2, 3, 4, 5))
print(my_list)

>>>  

    [1, 2, 3, 4, 5]

Эта встроенная функция очень полезна в некоторых частных случаях. Например, предположим, что мы хотим создать список чисел в диапазоне (1–10). Вот как мы можем это сделать:

# Create a list in a range
my_list = list(range(1, 10))
print(my_list)

>>>

  [1, 2, 3, 4, 5, 6, 7, 8, 9]
ПРИМЕЧАНИЕ:Помните, что встроенная функция «диапазон» включает в себя первое значение, и исключает последний.

Теперь давайте посмотрим, как мы можем манипулировать списками.

Манипуляции со списками

Благодаря тому, что списки изменяемы, у нас есть много возможностей ими манипулировать. Например, допустим, у нас есть список имен, но мы допустили ошибку и хотим его изменить. Вот как мы можем это сделать:

# List of names
names = ["James", "Richard", "Simon", "Elizabeth", "Tricia"]
# Change the wrong name
names[0] = "Alexander"
# Print list
print(names)

>>>
    
    ['Alexander', 'Richard', 'Simon', 'Elizabeth', 'Tricia']

Итак, в приведенном выше примере мы изменили имя списка с James на Alexander.

ПРИМЕЧАНИЕ:Если вы не знали, обратите внимание, что в Python первый элемент всегда доступен по "0", в зависимости от типа, которым мы манипулируем.
Итак, в приведенном выше примере "names[0]" представляет первый элемент списка "names".

Теперь предположим, что мы забыли имя. Мы можем добавить его в наш список следующим образом:

# List of names
names = ["James", "Richard", "Simon", "Elizabeth", "Tricia"]
# Append another name
names.append("Alexander")
# Print list
print(names) 

>>>

    ['James', 'Richard', 'Simon', 'Elizabeth', 'Tricia', 'Alexander']

Если нам нужно объединить два списка, у нас есть две возможности: метод concatenate или метод extend(). Давайте посмотрим на них:

# Create list1
list1 = [1, 2, 3]
# Create list2
list2 = [4, 5, 6]
# Concatenate lists
concatenated_list = list1 + list2
# Print concatenated list
print(concatenated_list)

>>>

  [1, 2, 3, 4, 5, 6]

Таким образом, этот метод создает список, являющийся суммой других списков. Давайте посмотрим на метод extend():

# Create list1
list1 = [1, 2, 3]
# Create list2
list2 = [4, 5, 6]
# Extend list1 with list2
list1.extend(list2)
# Print new list1
print(list1)

>>>

  [1, 2, 3, 4, 5, 6]

Как мы видим, результаты одинаковы, но синтаксис отличается. Этот метод расширяет list1 с помощью list2.

Если мы хотим удалить элементы, у нас есть две возможности: мы можем использовать метод remove() или метод del. Давайте посмотрим на них:

# Create list
my_list = [1, 2, 3, 'four', 5.0]
# Remove one element and print
my_list.remove('four')
print(my_list)

>>>

  [1, 2, 3, 5.0]

Давайте посмотрим на другой метод:

# Create list
my_list = [1, 2, 3, 'four', 5.0]
# Delete one element and print
del my_list[3]
print(my_list)

>>>

    [1, 2, 3, 5.0]

Таким образом, мы получаем одинаковые результаты с обоими методами, но remove() дает нам возможность явно написать удаляемый элемент, в то время как del необходимо получить доступ к позиции элемента списка.

ПРИМЕЧАНИЕ:Если вы уже знакомы с доступом к позициям, в приведенном выше пример my_list[3] = 'four'. Потому что, помните: в Python мы начинаем считать позиции с 0.

Много различных вариантов манипуляций списками. Предлагаем вам узнать, является ли переменная списком или информацию о связанных списках. Данные операции будут встречаться довольно часто при анализе данных в программировании, надеемся, что они вам помогут облегчить работу.

Понимание списка

Во многих случаях нам нужно создавать списки, начиная с существующих списков, обычно применяя некоторые фильтры к существующим данным. Для этого у нас есть две возможности:

  1. Мы используем циклы и операторы.
  2. Мы используем понимание списка.

На практике это один и тот же способ написания одного и того же, но понимание списка более лаконичное и элегантное.

Но прежде чем мы обсудим эти методы, вам может понадобиться глубокий обзор циклов и операторов. Вот пара статей, которые я написал в прошлом, которые могут вам помочь:

  1. Циклы в Python
  2. Функции Python

Теперь давайте посмотрим на пару примеров, использующих циклы и операторы напрямую.

Предположим, у нас есть список покупок. Мы хотим, чтобы наша программа напечатала, что мы любим один фрукт и что нам не нравятся другие в списке. Вот как мы можем это сделать:

# Create shopping list
shopping_list = ["banana", "apple", "orange", "lemon"]
# Print the one I like
for fruit in shopping_list:
    if fruit == "lemon":
        print(f"I love {fruit}")
    else:
        print(f"I don't like {fruit}")

>>>

    I don't like banana
    I don't like apple
    I don't like orange
    I love lemon

Другой пример может быть следующим. Предположим, у нас есть список чисел, и мы хотим напечатать только четные числа. Вот как мы можем это сделать:

# Create list
numbers = [1,2,3,4,5,6,7,8]
# Create empty list
even_list = []
# Print even numbers
for even in numbers:
    if even %2 == 0:
        even_list.append(even)
    else:
        pass
    
print(even_list)

>>>

    [2, 4, 6, 8]
ПРИМЕЧАНИЕ:Если вы не знакомы с синтаксисом %2 == 0, это означает, что мы делить число на 2 и ожидать напоминания о 0. Другими словами, мы просим нашу программу перехватывать четные числа.

Итак, в приведенном выше примере мы создали список чисел. Затем мы создали пустой список, который используется после цикла для добавления всех четных чисел. Таким образом, мы создали список четных чисел из списка с «общими» числами.

Итак… этот способ создания новых списков с циклами и операторами немного «тяжеловат». Я имею в виду: это требует много кода. Мы можем получить те же результаты более кратким способом, используя понимание списка.

Например, чтобы создать список с четными числами, мы можем использовать понимание списка следующим образом:

# Create list
numbers = [1,2,3,4,5,6,7,8]
# Create list of even numbers
even_numbers = [even for even in numbers if even %2 == 0]
# Print even list
print(even_numbers)

>>>

    [2, 4, 6, 8]

Итак, понимание списка создает непосредственно новый список, и мы определяем условие внутри него. Как мы видим, мы получаем тот же результат, что и раньше, но всего одной строкой кода: неплохо!

Теперь давайте создадим список с комментариями о fruit, которые я люблю (и о fruit, которые не люблю) с пониманием списка:

# Create shipping list
shopping_list = ["banana", "apple", "orange", "lemon"]
# Create commented list and print it
commented_list = [f"I love {fruit}" if fruit == "banana"
                  else f"I don't like {fruit}"
                  for fruit in shopping_list]
print(commented_list)

>>>
  
  ['I love banana', "I don't like apple", "I don't like orange",
   "I don't like lemon"]

Итак, мы получили тот же результат, что и раньше, но с помощью всего одной строчки кода. Единственная разница в том, что здесь мы напечатали список (потому что списковое понимание создает его!), а раньше мы просто печатали результаты.

Список списков

Существует также возможность создавать списки списков, то есть списки, вложенные в один список. Эта возможность полезна, когда мы хотим представить перечисленные данные в виде уникального списка.

Например, предположим, что мы хотим создать список студентов и их оценок. Мы могли бы создать что-то вроде этого:

# Create lis with students and their grades
students = [
    ["John", [85, 92, 78, 90]],
    ["Emily", [77, 80, 85, 88]],
    ["Michael", [90, 92, 88, 94]],
    ["Sophia", [85, 90, 92, 87]]
]

Это полезное обозначение, если, например, мы хотим рассчитать среднюю оценку для каждого учащегося. Мы можем сделать это так:

# Iterate over the list
for student in students:
    name = student[0] # Access names
    grades = student[1] # Access grades
    average_grade = sum(grades) / len(grades) # Calculate mean grades
    print(f"{name}'s average grade is {average_grade:.2f}")

>>>

    John's average grade is 86.25
    Emily's average grade is 82.50
    Michael's average grade is 91.00
    Sophia's average grade is 88.50

Кортежи

Кортежи — это еще один тип структуры данных в Python. Они определяются с помощью круглых скобок и, как списки, могут содержать данные любого типа, разделенные запятой. Итак, например, мы можем определить кортеж следующим образом:

# Define a tuple and print it
my_tuple = (1, 3.0, "John")
print(my_tuple)

>>>

    (1, 3.0, 'John')

Разница между кортежем и списком в том, что кортеж неизменяем. Это означает, что элементы кортежа не могут быть изменены. Так, например, если мы попытаемся добавить значение к кортежу, мы получим ошибку:

# Create a tuple with names
names = ("James", "Jhon", "Elizabeth")
# Try to append a name
names.append("Liza")

>>>

    AttributeError: 'tuple' object has no attribute 'append'

Итак, поскольку мы не можем изменять кортежи, они полезны, когда мы хотим, чтобы наши данные были неизменяемыми; например, в ситуациях, когда мы не хотим совершать ошибки.

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

# Create a chart as a tuple
cart = (
    ("Shirt", 2, 19.99),
    ("Shoes", 1, 59.99),
    ("Watch", 1, 99.99)
)

Конечно, если быть точным, это кортеж кортежей.

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

Наконец, аналогично спискам, мы можем создать кортеж с помощью встроенной функции tuple() следующим образом:

# Create a tuple in a range
my_tuple = tuple(range(1, 10))
print(my_tuple)

>>>

  (1, 2, 3, 4, 5, 6, 7, 8, 9)

Словари

Словарь — это способ хранения данных, связанных как ключи и значения. Вот как мы можем создать его:

# Create a dictionary
my_dictionary = {'key_1':'value_1', 'key_2':'value_2'}

Итак, мы создаем словарь с фигурными скобками и храним в нем пару ключей и значений, разделенных двоеточием. Затем пары "ключ-значение" разделяются запятой.

Теперь давайте посмотрим, как мы можем манипулировать словарями.

Работа со словарями

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

# Create a dictionary of numbers and print it
numbers = {1:'one', 2:'two', 3:'three'}
print(numbers)

>>>

    {1: 'one', 2: 'two', 3: 'three'}

Но мы можем создать и такой:

# Create a dictionary of numbers and print it
numbers = {'one':1, 'two':2.0, 3:'three'}
print(numbers)

>>>

  {'one': 1, 'two': 2.0, 3: 'three'}

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

# Access values and keys
keys = list(numbers.keys())
values = tuple(numbers.values())
# Print values and keys
print(f"The keys are: {keys}")
print(f"The values are: {values}")

>>>

    The keys are: ['one', 'two', 3]
    The values are: (1, 2.0, 'three')

Итак, если наш словарь называется numbers, мы получаем доступ к его ключу с помощью numbers.keys(). А с помощью numbers.values() мы получаем доступ к его значениям. Также обратите внимание, что мы создали список с ключами и кортеж со значениями, используя обозначение, которое мы видели ранее.

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

# Create a shopping list with fruits and prices
shopping_list = {'banana':2, 'apple':1, 'orange':1.5}
# Iterate over the values
for values in shopping_list.values():
    # Values greater than threshold
    if values > 1:
        print(values)

>>>

    2
    1.5

Как и списки, словари изменяемы. Итак, если мы хотим добавить значение в словарь, мы должны определить ключ и значение, которое нужно добавить к нему. Мы можем сделать это так:

# Create the dictionary
person = {'name': 'John', 'age': 30}
# Add value and key and print
person['city'] = 'New York'
print(person)

>>>


    {'name': 'John', 'age': 30, 'city': 'New York'}

Чтобы изменить значение словаря, нам нужно получить доступ к его ключу:

# Create a dictionary
person = {'name': 'John', 'age': 30}
# Change age value and print
person['age'] = 35
print(person)


>>>

    {'name': 'John', 'age': 35}

Чтобы удалить пару ключ-значение из словаря, нам нужно получить доступ к ее ключу:

# Create dictionary
person = {'name': 'John', 'age': 30}
# Delete age and print
del person['age']
print(person)


>>>

    {'name': 'John'}

Вложенные словари

Мы уже видели, что можем создавать списки из списков и кортежи из кортежей. Точно так же мы можем создавать вложенные словари. Предположим, например, что мы хотим создать словарь для хранения данных, относящихся к классу студентов. Мы можем сделать это так:

# Create a classroom dictionary
classroom = {
    'student_1': {
        'name': 'Alice',
        'age': 15,
        'grades': [90, 85, 92]
    },
    'student_2': {
        'name': 'Bob',
        'age': 16,
        'grades': [80, 75, 88]
    },
    'student_3': {
        'name': 'Charlie',
        'age': 14,
        'grades': [95, 92, 98]
    }

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

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

# Access student_3 and print
student_3 = classroom['student_3']
print(student_3)


>>>

    {'name': 'Charlie', 'age': 14, 'grades': [95, 92, 98]}

Понимание словарей

Понимание словаря позволяет нам создавать словари лаконично и эффективно. Это похоже на понимание списка, но вместо создания списка он создает словарь.

Предположим, у нас есть словарь, в котором мы сохранили некоторые объекты и их цены. Мы хотим знать объекты, которые стоят меньше определенного порога. Мы можем сделать это так:

# Define initial dictionary
products = {'shoes': 100, 'watch': 50, 'smartphone': 250, 'tablet': 120}
# Define threshold
max_price = 150
# Filter for threshold
products_to_buy = {fruit: price for fruit, price in products.items() if price <= max_price}
# Print filtered dictionary
print(products_to_buy)

>>>

    {'shoes': 100, 'watch': 50, 'tablet': 120}

Итак, синтаксис для использования понимания словаря:

new_dict = {key:value for key, value in iterable}

Где iterable — любой итерируемый объект Python. Это может быть список, кортеж, другой словарь и т. д.

Создание словарей «стандартным» методом потребовало бы большого количества кода с условиями, циклами и операторами. Вместо этого, как мы видим, понимание словаря позволяет нам создать словарь на основе условий всего одной строкой кода.

Понимание словаря особенно полезно, когда нам нужно создать словарь, извлекающий данные из других источников или структур данных. Например, нам нужно создать словарь, извлекающий значения из двух списков. Мы можем сделать это так:

# Define names and ages in lists
names = ['John', 'Jane', 'Bob', 'Alice']
cities = ['New York', 'Boston', 'London', 'Rome']
# Create dictionary from lists and print results
name_age_dict = {name: city for name, city in zip(names, cities)}
print(name_age_dict)


>>>


   {'John': 'New York', 'Jane': 'Boston', 'Bob': 'London', 'Alice': 'Rome'}

Фреймы данных

Фрейм данных — это представление табличных данных.

Изображение с веб-сайта Panda здесь: https://pandas.pydata.org/docs/getting_started/index.html

Фрейм данных — это двумерная структура данных, состоящая из столбцов и строк. Итак, это чем-то похоже на электронную таблицу или таблицу в базе данных SQL. Они имеют следующие характеристики:

  1. Каждая строка представляет отдельное наблюдение или запись.
  2. Каждый столбец представляет собой переменную или определенный атрибут данных.
  3. Они имеют помеченные строки (называемые индексами) и столбцы, что упрощает манипулирование данными.
  4. Столбцы могут содержать различные типы данных, например целые числа, строки или числа с плавающей запятой. Даже один столбец может содержать разные типы данных.

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

Вот как выглядит фрейм данных:

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

Основные операции с фреймами данных с помощью Pandas

Хотя недавно начала распространяться новая библиотека для управления фреймами данных под названием «Polars», здесь мы увидим некоторые манипуляции с данными с помощью Pandas, которые по-прежнему наиболее часто используются на сегодняшний день.

Прежде всего, как правило, мы можем создавать фреймы данных, импортируя данные из файлов .xlsx или .cvs. В Pandas мы можем сделать это так:

import pandas as pd

# Import cvs file
my_dataframe = pd.read_csv('a_file.csv')

# Import xlsx
my_dataframe_2 = pd.read_excel('a_file_2.xlsx')

Если мы хотим создать фрейм данных:

import pandas as pd

# Create a dictionary with different types of data
data = {
    'Name': ['John', 'Alice', 'Bob'],
    'Age': ['twenty-five', 30, 27],
    'City': ['New York', 'London', 'Sydney'],
    'Salary': [50000, 60000.50, 45000.75],
    'Is_Employed': [True, True, False]
}

# Create the dataframe
df = pd.DataFrame(data)

Это кадр данных, который мы показали выше. Итак, как мы видим, мы сначала создаем словарь, а затем преобразуем его во фрейм данных с помощью метода pd.DataFrame().

У нас есть три возможности визуализировать фрейм данных. Предположим, у нас есть фрейм данных с именем df:

  1. Первый — print(df).
  2. Второй — df.head(), который покажет первые 5 строк нашего фрейма данных. Если у нас есть фрейм данных с большим количеством строк, мы можем показать больше, чем первые пять. Например, df.head(20) показывает первые 20.
  3. Третий — df.tail(), который работает точно так же, как head(), но показывает последние строки.

Что касается визуализации, используя приведенный выше df, вот что показывает df.head():

И вот что показывает print(df):

В случае с небольшими наборами данных, такими как этот, разница только во вкусе (я предпочитаю функцию head(), потому что она «показывает табличность» данных). Но в случае больших наборов данных head() намного лучше. Попробуйте и дайте мне знать!

Учтите, что Pandas — очень широкая библиотека, то есть она позволяет нам манипулировать табличными данными различными способами, поэтому с ней нужно работать отдельно. Здесь мы хотим показать только самые основы, поэтому мы увидим, как мы можем добавлять и удалять столбец (столбцы фрейма данных также называются “Pandas series”).

Предположим, мы хотим добавить столбец во фрейм данных df, который мы видели выше, который сообщает нам, состоят ли люди в браке или нет. Мы можем сделать это так:

# Add marital status
df["married"] = ["yes", "yes", "no"]
ПРИМЕЧАНИЕ:Это та же нотация, которую мы использовали для добавления значений в словарь. Вернитесь к статье и сравните два метода.

И показывая голову, мы имеем:

Чтобы удалить один столбец:

# Delete the "Is_Employed" column
df = df.drop('Is_Employed', axis=1)

И мы получаем:

Обратите внимание, что нам нужно использовать axis=1, потому что здесь мы говорим Pandas удалить столбцы, а поскольку фрейм данных представляет собой двумерную структуру данных, axis=1 представляет вертикальное направление.

Вместо этого, если мы хотим удалить строку, нам нужно использовать axis=1. Например, предположим, что мы хотим удалить строку, связанную с индексом 1 (это вторая строка, потому что мы снова начинаем считать с 0):

# Delete the second row 
df = df.drop(1, axis=0)

И мы получаем:

Выводы

До сих пор мы видели наиболее часто используемые структуры данных в Python. Это не единственные, но, безусловно, наиболее используемые.

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

Я надеюсь, что эта статья помогла вам понять, как использовать эти структуры данных и когда их использовать.

Источник:

#Python #Data Science #Machine Learning
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу