Библиотека Pandas для работы с данными
Pandas — программная библиотека на языке Python для обработки и анализа данных. Работа pandas с данными строится поверх библиотеки NumPy, являющейся инструментом более низкого уровня. Предоставляет специальные структуры данных и операции для манипулирования числовыми таблицами и временны́ми рядами.
Главный элемент пандаса — DataFrame (датафрейм, df), с которым можно производить необходимые преобразования. df — “таблица”, состоящая из строк и столбцов. По умолчанию, строчки таблицы — это объекты, а столбцы — признаки (фичи) объектов.
import pandas as pd import numpy as np
Создание DataFrame
d = 'feature1': [4,3,2,1,0], 'feature2': ['x', 'z', 'y', 'x', 'z'], 'feature3': [2,3,4,1,0]> df = pd.DataFrame(d) df
feature1 | feature2 | feature3 | |
---|---|---|---|
0 | 4 | x | 2 |
1 | 3 | z | 3 |
2 | 2 | y | 4 |
3 | 1 | x | 1 |
4 | 0 | z | 0 |
data = [['tom', 10], ['nick', 15], ['juli', 14]] df = pd.DataFrame(data, columns = ['Name', 'Age']) df
Name | Age | |
---|---|---|
0 | tom | 10 |
1 | nick | 15 |
2 | juli | 14 |
data = 'Name':['Tom', 'Jack', 'nick', 'juli'], 'marks':[99, 98, 95, 90]> df = pd.DataFrame(data, index =['rank1', 'rank2', 'rank3', 'rank4']) df
Name | marks | |
---|---|---|
rank1 | Tom | 99 |
rank2 | Jack | 98 |
rank3 | nick | 95 |
rank4 | juli | 90 |
data = ['a': 1, 'b': 2, 'c':3>, 'a':10, 'b': 20>] df = pd.DataFrame(data) df
a | b | c | |
---|---|---|---|
0 | 1 | 2 | 3.0 |
1 | 10 | 20 | NaN |
d = 'one' : pd.Series([10, 20, 30, 40], index =['a', 'b', 'c', 'd']), 'two' : pd.Series([10, 20, 30, 40], index =['a', 'b', 'c', 'd'])> df = pd.DataFrame(d) df
one | two | |
---|---|---|
a | 10 | 10 |
b | 20 | 20 |
c | 30 | 30 |
d | 40 | 40 |
Первичный анализ данных с Pandas
Pandas — это библиотека Python, предоставляющая широкие возможности для анализа данных. С ее помощью очень удобно загружать, обрабатывать и анализировать табличные данные с помощью SQL-подобных запросов. В связке с библиотеками Matplotlib и Seaborn появляется возможность удобного визуального анализа табличных данных.
Данные, с которыми работают датсаентисты и аналитики, обычно хранятся в виде табличек — например, в форматах .csv, .tsv или .xlsx. Для того, чтобы считать нужные данные из такого файла, отлично подходит библиотека Pandas.
Основными структурами данных в Pandas являются классы Series и DataFrame. Первый из них представляет собой одномерный индексированный массив данных некоторого фиксированного типа. Второй — это двухмерная структура данных, представляющая собой таблицу, каждый столбец которой содержит данные одного типа. Можно представлять её как словарь объектов типа Series. Структура DataFrame отлично подходит для представления реальных данных: строки соответствуют признаковым описаниям отдельных объектов, а столбцы соответствуют признакам.
pd.read_csv('beauty.csv', nrows=2)
wage;exper;union;goodhlth;black;female;married;service;educ;looks | |
---|---|
0 | 5.73;30;0;1;0;1;1;1;14;4 |
1 | 4.28;28;0;1;0;1;1;0;12;3 |
#help(pd.read_csv) path_to_file = 'beauty.csv' data = pd.read_csv(path_to_file, sep=';') print(data.shape) #df.tail() data.head()
(1260, 10)
wage | exper | union | goodhlth | black | female | married | service | educ | looks | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 5.73 | 30 | 0 | 1 | 0 | 1 | 1 | 1 | 14 | 4 |
1 | 4.28 | 28 | 0 | 1 | 0 | 1 | 1 | 0 | 12 | 3 |
2 | 7.96 | 35 | 0 | 1 | 0 | 1 | 0 | 0 | 10 | 4 |
3 | 11.57 | 38 | 0 | 1 | 0 | 0 | 1 | 1 | 16 | 3 |
4 | 11.42 | 27 | 0 | 1 | 0 | 0 | 1 | 0 | 16 | 3 |
Мы считали данные по модельному бизнесу 80-90е года в США
type(data)
pandas.core.frame.DataFrame
#data.shape len(data)
1260
Чтобы посмотреть общую информацию по датафрейму и всем признакам, воспользуемся методом info:
data.info()
RangeIndex: 1260 entries, 0 to 1259 Data columns (total 10 columns): wage 1260 non-null float64 exper 1260 non-null int64 union 1260 non-null int64 goodhlth 1260 non-null int64 black 1260 non-null int64 female 1260 non-null int64 married 1260 non-null int64 service 1260 non-null int64 educ 1260 non-null int64 looks 1260 non-null int64 dtypes: float64(1), int64(9) memory usage: 98.6 KB
int64 и float64 — это типы признаков. Видим, что 1 признак — float64 и 9 признаков имеют тип int64.
Метод describe показывает основные статистические характеристики данных по каждому числовому признаку (типы int64 и float64): число непропущенных значений, среднее, стандартное отклонение, диапазон, медиану, 0.25 и 0.75 квартили.
data.describe()
wage | exper | union | goodhlth | black | female | married | service | educ | looks | |
---|---|---|---|---|---|---|---|---|---|---|
count | 1260.000000 | 1260.000000 | 1260.000000 | 1260.000000 | 1260.000000 | 1260.000000 | 1260.000000 | 1260.000000 | 1260.000000 | 1260.000000 |
mean | 6.306690 | 18.206349 | 0.272222 | 0.933333 | 0.073810 | 0.346032 | 0.691270 | 0.273810 | 12.563492 | 3.185714 |
std | 4.660639 | 11.963485 | 0.445280 | 0.249543 | 0.261564 | 0.475892 | 0.462153 | 0.446089 | 2.624489 | 0.684877 |
min | 1.020000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 5.000000 | 1.000000 |
25% | 3.707500 | 8.000000 | 0.000000 | 1.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 12.000000 | 3.000000 |
50% | 5.300000 | 15.000000 | 0.000000 | 1.000000 | 0.000000 | 0.000000 | 1.000000 | 0.000000 | 12.000000 | 3.000000 |
75% | 7.695000 | 27.000000 | 1.000000 | 1.000000 | 0.000000 | 1.000000 | 1.000000 | 1.000000 | 13.000000 | 4.000000 |
max | 77.720000 | 48.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 17.000000 | 5.000000 |
Посмотрим на признак “exper” — рабочий стаж
data['exper'].head() #data.exper.head() # 2-ой вариант
0 30 1 28 2 35 3 38 4 27 Name: exper, dtype: int64
Как описывалось ранее — тип данных в колонке является Series, что по сути является проиндексированным массивом
type(data['exper'])
pandas.core.series.Series
loc и iloc
С помощью loc и iloc — можно из начального датафрейма зафиксировать определённые интервал строк и интересующих столбцов и работать/смотреть только их
#data.loc[1:5, ['wage']] data.wage.loc[1:5]
1 4.28 2 7.96 3 11.57 4 11.42 5 3.91 Name: wage, dtype: float64
#data.iloc[0,1] # первое число - номер столбца (начинается с 0). Второе - индекс строчки data['wage'].iloc[1:5]
1 4.28 2 7.96 3 11.57 4 11.42 Name: wage, dtype: float64
Условия
Посмотрим на наш датафрейм, на соответствие какому-то условию
(data['exper'] >= 15)
0 True 1 True 2 True 3 True 4 True . 1255 True 1256 False 1257 True 1258 True 1259 True Name: exper, Length: 1260, dtype: bool
Посмотрим только те строки, в датафрейме, которые удовлетворяют определённому условию, и выведем первые 5 из них
data[(data['female'] == 1) & (data['black'] == 1)].head(10)
wage | exper | union | goodhlth | black | female | married | service | educ | looks | |
---|---|---|---|---|---|---|---|---|---|---|
44 | 4.95 | 20 | 0 | 1 | 1 | 1 | 0 | 1 | 14 | 3 |
85 | 10.12 | 40 | 0 | 1 | 1 | 1 | 0 | 1 | 10 | 3 |
110 | 3.37 | 36 | 0 | 1 | 1 | 1 | 0 | 1 | 13 | 3 |
148 | 7.21 | 20 | 1 | 0 | 1 | 1 | 1 | 1 | 17 | 3 |
167 | 2.81 | 14 | 0 | 1 | 1 | 1 | 1 | 0 | 13 | 3 |
211 | 2.88 | 7 | 0 | 1 | 1 | 1 | 0 | 1 | 13 | 4 |
497 | 7.07 | 8 | 1 | 1 | 1 | 1 | 0 | 0 | 13 | 3 |
499 | 3.89 | 4 | 0 | 1 | 1 | 1 | 0 | 0 | 16 | 4 |
504 | 6.54 | 8 | 0 | 1 | 1 | 1 | 0 | 0 | 13 | 3 |
507 | 7.69 | 16 | 0 | 1 | 1 | 1 | 1 | 0 | 13 | 3 |
Посмотрим только те строки, которые удовлетворяют условию и выведем значение определённого столбца
data[data['female'] == 1]['wage'].head(10)
0 5.73 1 4.28 2 7.96 5 3.91 8 5.00 9 3.89 10 3.45 18 10.44 19 7.69 44 4.95 Name: wage, dtype: float64
data[(data['female'] == 0) & (data['married'] == 1)].head(10)
wage | exper | union | goodhlth | black | female | married | service | educ | looks | |
---|---|---|---|---|---|---|---|---|---|---|
3 | 11.57 | 38 | 0 | 1 | 0 | 0 | 1 | 1 | 16 | 3 |
4 | 11.42 | 27 | 0 | 1 | 0 | 0 | 1 | 0 | 16 | 3 |
6 | 8.76 | 12 | 0 | 1 | 0 | 0 | 1 | 0 | 16 | 3 |
11 | 4.03 | 6 | 0 | 1 | 0 | 0 | 1 | 0 | 16 | 4 |
12 | 5.14 | 19 | 0 | 1 | 0 | 0 | 1 | 1 | 17 | 2 |
14 | 7.99 | 12 | 0 | 1 | 0 | 0 | 1 | 0 | 16 | 4 |
15 | 6.01 | 17 | 0 | 1 | 0 | 0 | 1 | 0 | 16 | 4 |
16 | 5.16 | 7 | 0 | 1 | 0 | 0 | 1 | 0 | 17 | 3 |
17 | 11.54 | 12 | 0 | 1 | 0 | 0 | 1 | 1 | 17 | 4 |
21 | 6.79 | 19 | 0 | 1 | 0 | 0 | 1 | 1 | 14 | 3 |
# Метод describe для сложного условия data[(data['female'] == 0) & (data['married'] == 1)].describe()
wage | exper | union | goodhlth | black | female | married | service | educ | looks | |
---|---|---|---|---|---|---|---|---|---|---|
count | 658.000000 | 658.000000 | 658.000000 | 658.000000 | 658.000000 | 658.0 | 658.0 | 658.000000 | 658.000000 | 658.000000 |
mean | 7.716778 | 22.136778 | 0.308511 | 0.937690 | 0.037994 | 0.0 | 1.0 | 0.194529 | 12.495441 | 3.164134 |
std | 4.798763 | 11.714753 | 0.462230 | 0.241902 | 0.191327 | 0.0 | 0.0 | 0.396139 | 2.716007 | 0.655469 |
min | 1.050000 | 1.000000 | 0.000000 | 0.000000 | 0.000000 | 0.0 | 1.0 | 0.000000 | 5.000000 | 1.000000 |
25% | 4.810000 | 12.000000 | 0.000000 | 1.000000 | 0.000000 | 0.0 | 1.0 | 0.000000 | 12.000000 | 3.000000 |
50% | 6.710000 | 20.500000 | 0.000000 | 1.000000 | 0.000000 | 0.0 | 1.0 | 0.000000 | 12.000000 | 3.000000 |
75% | 8.890000 | 32.000000 | 1.000000 | 1.000000 | 0.000000 | 0.0 | 1.0 | 0.000000 | 13.000000 | 4.000000 |
max | 41.670000 | 48.000000 | 1.000000 | 1.000000 | 1.000000 | 0.0 | 1.0 | 1.000000 | 17.000000 | 5.000000 |
Посчитаем средние значения из тех данных, что удовлетворяют условию
data[data['female'] == 1]['wage'].mean(), data[data['female'] == 0]['wage'].mean() # .std, .min, .max, .count
(4.299357798165136, 7.3688228155339734)
Вывод медианного значения, для данных, удовлетворяющих сложному условию
data[(data['female'] == 0) & (data['married'] == 1)]['wage'].median(), \ data[(data['female'] == 0) & (data['married'] == 0)]['wage'].median()
(6.710000000000001, 5.0649999999999995)
data['wage'].nunique()
Ниже приводятся примеры использования метода groupby для отображения информации по сгруппированному признаку
data.groupby('looks').wage.count()
looks 1 13 2 142 3 722 4 364 5 19 Name: wage, dtype: int64
for look, sub_df in data.drop(['goodhlth'],axis=1).groupby('looks'): print(look) print(sub_df.head()) print()
1 wage exper union black female married service educ looks 28 8.35 41 0 0 0 1 1 16 1 200 3.75 36 0 0 0 0 0 12 1 248 10.99 40 0 0 0 1 0 12 1 327 1.65 24 0 0 1 0 1 13 1 751 7.93 39 1 0 0 1 0 12 1 2 wage exper union black female married service educ looks 12 5.14 19 0 0 0 1 1 17 2 33 8.17 18 0 0 0 1 0 16 2 35 9.62 37 0 0 0 1 0 13 2 37 7.69 10 1 0 0 1 0 13 2 57 6.56 17 0 0 0 1 0 13 2 3 wage exper union black female married service educ looks 1 4.28 28 0 0 1 1 0 12 3 3 11.57 38 0 0 0 1 1 16 3 4 11.42 27 0 0 0 1 0 16 3 5 3.91 20 0 0 1 1 0 12 3 6 8.76 12 0 0 0 1 0 16 3 4 wage exper union black female married service educ looks 0 5.73 30 0 0 1 1 1 14 4 2 7.96 35 0 0 1 0 0 10 4 7 7.69 5 1 0 0 0 0 16 4 10 3.45 3 0 0 1 0 0 12 4 11 4.03 6 0 0 0 1 0 16 4 5 wage exper union black female married service educ looks 26 14.84 29 0 0 0 0 1 13 5 27 19.08 17 0 0 0 0 0 17 5 76 23.32 15 0 0 0 1 1 17 5 112 6.11 7 0 0 1 1 0 12 5 316 3.92 12 0 0 0 1 1 12 5
for look, sub_df in data.groupby('looks'): print(look) print(sub_df['wage'].median()) print()
1 3.46 2 4.595000000000001 3 5.635 4 5.24 5 4.81
for look, sub_df in data.groupby('looks'): print(look) print(round(sub_df['female'].mean(), 3)) print()
1 0.385 2 0.38 3 0.323 4 0.374 5 0.421
for look, sub_df in data.groupby(['looks', 'female']): print(look) print(sub_df['goodhlth'].mean()) print()
(1, 0) 0.75 (1, 1) 1.0 (2, 0) 0.9431818181818182 (2, 1) 0.9259259259259259 (3, 0) 0.9304703476482618 (3, 1) 0.9012875536480687 (4, 0) 0.9649122807017544 (4, 1) 0.9411764705882353 (5, 0) 1.0 (5, 1) 1.0
С помощью .agg метод groupby может применять различные функции к данным, что он получает
data.groupby('looks')[['wage', 'exper']].max()
wage | exper | |
---|---|---|
looks | ||
1 | 10.99 | 41 |
2 | 26.24 | 45 |
3 | 38.86 | 48 |
4 | 77.72 | 47 |
5 | 23.32 | 32 |
Декартово произведение признаков из столбцов и их отображение
pd.crosstab(data['female'], data['married'])
married | 0 | 1 |
---|---|---|
female | ||
0 | 166 | 658 |
1 | 223 | 213 |
pd.crosstab(data['female'], data['looks'])
looks | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
female | |||||
0 | 8 | 88 | 489 | 228 | 11 |
1 | 5 | 54 | 233 | 136 | 8 |
Создание нового признака из наложения дополнительных условий на основе старых данных
data['exp'] = (data['exper'] >=15).astype(int) data.head(10)
wage | exper | union | goodhlth | black | female | married | service | educ | looks | exp | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 5.73 | 30 | 0 | 1 | 0 | 1 | 1 | 1 | 14 | 4 | 1 |
1 | 4.28 | 28 | 0 | 1 | 0 | 1 | 1 | 0 | 12 | 3 | 1 |
2 | 7.96 | 35 | 0 | 1 | 0 | 1 | 0 | 0 | 10 | 4 | 1 |
3 | 11.57 | 38 | 0 | 1 | 0 | 0 | 1 | 1 | 16 | 3 | 1 |
4 | 11.42 | 27 | 0 | 1 | 0 | 0 | 1 | 0 | 16 | 3 | 1 |
5 | 3.91 | 20 | 0 | 0 | 0 | 1 | 1 | 0 | 12 | 3 | 1 |
6 | 8.76 | 12 | 0 | 1 | 0 | 0 | 1 | 0 | 16 | 3 | 0 |
7 | 7.69 | 5 | 1 | 1 | 0 | 0 | 0 | 0 | 16 | 4 | 0 |
8 | 5.00 | 5 | 0 | 1 | 0 | 1 | 0 | 0 | 16 | 3 | 0 |
9 | 3.89 | 12 | 0 | 1 | 0 | 1 | 0 | 0 | 12 | 3 | 0 |
new = data[data['female'] == 1] new.to_csv('new.csv', index=False) new.head()
wage | exper | union | goodhlth | black | female | married | service | educ | looks | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 5.73 | 30 | 0 | 1 | 0 | 1 | 1 | 1 | 14 | 4 |
1 | 4.28 | 28 | 0 | 1 | 0 | 1 | 1 | 0 | 12 | 3 |
2 | 7.96 | 35 | 0 | 1 | 0 | 1 | 0 | 0 | 10 | 4 |
5 | 3.91 | 20 | 0 | 0 | 0 | 1 | 1 | 0 | 12 | 3 |
8 | 5.00 | 5 | 0 | 1 | 0 | 1 | 0 | 0 | 16 | 3 |
data['wage'].sort_values(ascending=False).head(3)
602 77.72 269 41.67 415 38.86 Name: wage, dtype: float64
data['is_rich'] = (data['wage'] > data['wage'].quantile(.75)).astype('int64')
data['wage'].quantile(.75)
7.695
data.head()
wage | exper | union | goodhlth | black | female | married | service | educ | looks | exp | is_rich | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 5.73 | 30 | 0 | 1 | 0 | 1 | 1 | 1 | 14 | 4 | 1 | 0 |
1 | 4.28 | 28 | 0 | 1 | 0 | 1 | 1 | 0 | 12 | 3 | 1 | 0 |
2 | 7.96 | 35 | 0 | 1 | 0 | 1 | 0 | 0 | 10 | 4 | 1 | 1 |
3 | 11.57 | 38 | 0 | 1 | 0 | 0 | 1 | 1 | 16 | 3 | 1 | 1 |
4 | 11.42 | 27 | 0 | 1 | 0 | 0 | 1 | 0 | 16 | 3 | 1 | 1 |
data['rubbish'] = .56 * data['wage'] + 0.32 * data['exper'] data.head()
wage | exper | union | goodhlth | black | female | married | service | educ | looks | exp | is_rich | rubbish | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 5.73 | 30 | 0 | 1 | 0 | 1 | 1 | 1 | 14 | 4 | 1 | 0 | 12.8088 |
1 | 4.28 | 28 | 0 | 1 | 0 | 1 | 1 | 0 | 12 | 3 | 1 | 0 | 11.3568 |
2 | 7.96 | 35 | 0 | 1 | 0 | 1 | 0 | 0 | 10 | 4 | 1 | 1 | 15.6576 |
3 | 11.57 | 38 | 0 | 1 | 0 | 0 | 1 | 1 | 16 | 3 | 1 | 1 | 18.6392 |
4 | 11.42 | 27 | 0 | 1 | 0 | 0 | 1 | 0 | 16 | 3 | 1 | 1 | 15.0352 |
Контест для проверки понимания ссылка.
Домашнее задание будет во 2ой части
Сайт построен с использованием Pelican. За основу оформления взята тема от Smashing Magazine. Исходные тексты программ, приведённые на этом сайте, распространяются под лицензией GPLv3, все остальные материалы сайта распространяются под лицензией CC-BY.
Pandas
Pandas — это библиотека Python для обработки и анализа структурированных данных, её название происходит от «panel data» («панельные данные»). Панельными данными называют информацию, полученную в результате исследований и структурированную в виде таблиц. Для работы с такими массивами данных и создан Pandas.
Освойте профессию «Аналитик данных»
Работа с открытым кодом
Pandas — это opensource-библиотека, то есть ее исходный код в открытом доступе размещен на GitHub. Пользователи могут добавлять туда свой код: вносить пояснения, дополнять методы работы и обновлять разделы. Для работы потребуется компилятор (программа, которая переводит текст с языка программирования в машинный код) C/C++ и среда разработки Python. Подробный процесс установки компилятора С для разных операционных систем можно найти в документации Pandas.
Профессия / 12 месяцев
Аналитик данных
Находите закономерности и делайте выводы, которые помогут бизнесу
В каких профессиях понадобится библиотека?
Навык работы с этой библиотекой пригодится дата-сайентистам или аналитикам данных. С помощью Pandas эти специалисты могут группировать и визуализировать данные, создавать сводные таблицы и делать выборку по определенным признакам.
Как установить Pandas
Пошаговая инструкция по установке библиотеки Pandas
-
Скачать библиотеку На официальном сайте Pandas указан самый простой способ начать работу с библиотекой. Для этого потребуется установить Anaconda — дистрибутив (форма распространения программного обеспечения, набор библиотек или программного кода для установки программы) для Python с набором библиотек. Безопасно скачать его можно на официальном сайте.
Настройка установки Вот несколько советов по установке Anaconda для новичков:
— Выбирайте рекомендованные настройки, на первое время этого будет достаточно. Например, Install for: Just me (recommended).
— Но если не поставить галочку «Add Anaconda to my PATH environment variable», то Anaconda не будет запускаться по умолчанию, каждый раз ее нужно будет запускать отдельно.
— На вопрос: «Do you wish to initialize Anaconda3?» (Хотите ли вы инициализировать Anaconda3?) отвечайте «Да».
— После завершения установки перезагрузите компьютер.
Запуск JupyterLab В командной строке Anaconda запустите JupyterLab — это интерактивная среда для работы с кодом, данными и блокнотами, которая входит в пакет дистрибутива. Для этого введите jupyter-lab .
Открытие блокнота Создайте в JupyterLab новый блокнот Python3. Для его создания надо щелкнуть на значке «+», расположенном в верхней левой части интерфейса. В появившемся меню выбрать «Python 3» для создания блокнота.
Импорт библиотеки В первой ячейке пропишите: import pandas as pd , после этого в следующих ячейках можно писать код.
Читайте также Как выбрать IT-специальность в новых реалиях?
DataFrame и Series
Чтобы анализировать данные с помощью Pandas, нужно понять, как устроены структуры этих данных внутри библиотеки. В первую очередь разберем, что такое DataFrame и Series.
Series
Pandas Series (серия) — это одномерный массив. Визуально он похож на пронумерованный список: слева в колонке находятся индексы элементов, а справа — сами элементы.
my_series = pd.Series([5, 6, 7, 8, 9, 10])
Индексом может быть числовой показатель (0, 1, 2…), буквенные значения (a, b, c…) или другие данные, выбранные программистом. Если особое значение не задано, то числовые индексы проставляются автоматически. Например, от 0 до 5 как в примере выше.
Такая нумерация называется RangeIndex, в ней всегда содержатся числа от 0 до определенного числа N, которое обозначает количество элементов в серии. Собственные значения индексов задаются в квадратных скобках через index, как в примере ниже:
my_series2 = pd.Series([5, 6, 7, 8, 9, 10]), index=['a', 'b', 'c', 'd', 'e', 'f'])
Индексы помогают обращаться к элементам серии и менять их значения. Например, чтобы в нашей серии [5, 6, 7, 8, 9, 10] заменить значения некоторых элементов на 0, мы прописываем индексы нужных элементов и указываем, что они равны нулю:
my_series2[['a', 'b', 'f']] = 0
Можно сделать выборку по нескольким индексам, чтобы ненужные элементы в серии не отображались:
my_series2[['a', 'b', 'f']]
a 5 b 6 f 10 dtype: int64
DataFrame
Pandas DataFrame — это двумерный массив, похожий на таблицу/лист Excel (кстати, данные из Excel можно читать с помощью команды pandas.read_excel(‘file.xls’)) . В нем можно проводить такие же манипуляции с данными: объединять в группы, сортировать по определенному признаку, производить вычисления. Как любая таблица, датафрейм состоит из столбцов и строк, причем столбцами будут уже известные объекты — Series.
Чтобы проверить, действительно ли серии — это части датафрейма, можно извлечь любую колонку из таблицы. Возьмем набор данных о нескольких странах СНГ, их площади и населении и выберем колонку country:
df = pd.DataFrame(< 'country': ['Kazakhstan', 'Russia', 'Belarus', 'Ukraine'], 'population': [17.04, 143.5, 9.5, 45.5], 'square': [2724902, 17125191, 207600, 603628] >)
В итоге получится простая серия, в которой сохранятся те же индексы по строкам, что и в исходном датафрейме:
df['country']
type(df['country'])
Станьте аналитиком данных и получите востребованную специальность
Кроме этого, у датафрейма есть индексы по столбцам, которые задаются вручную. Для простоты написания кода обозначим страны индексами из двух символов: Kazakhstan — KZ, Russia — RU и так далее:
# Создаем датафрейм с заданными индексами df = pd.DataFrame(< 'country': ['Kazakhstan', 'Russia', 'Belarus', 'Ukraine'], 'population': [17.04, 143.5, 9.5, 45.5], 'square': [2724902, 17125191, 207600, 603628] >, index=['KZ', 'RU', 'BY', 'UA'])
# Изменяем индексы df.index = ['KZ', 'RU', 'BY', 'UA'] df.index.name = 'Country Code'
По индексам можно искать объекты и делать выборку, как в Series . Возьмем тот же датафрейм и сделаем выборку по индексам KZ, RU и колонке population методом .loc (в случае .loc мы используем квадратные скобки, а не круглые, как с другими методами), чтобы сравнить население двух стран:
df.loc[['KZ', 'RU'], 'population']
Anaconda выведет следующее:
Country Code
KZ 17.04
RU 143.50
Name: population, dtype: float64
Также в DataFrame производят математические вычисления. Например, рассчитаем плотность населения каждой страны в нашем датафрейме. Данные в колонке population (численность населения) делим на square (площадь) и получаем новые данные в колонке density, которые показывают плотность населения:
# Вычисление плотности населения df['density'] = df['population'] / df['square'] * 1000000
Станьте аналитиком данных и получите востребованную специальность
Чтение и запись данных
В Pandas работают с форматами csv, excel, sql, html, hdf и другими. Полный список можно посмотреть с помощью метода .read, где через нижнее подчеркивание «_» будут указаны все доступные форматы.
Ниже представлены примеры чтения и записи данных на Python с использованием Pandas:
Чтение данных:
- Чтение данных из CSV файла:
import pandas as pd # Чтение CSV файла data = pd.read_csv('data.csv') # Вывод первых нескольких строк датафрейма print(data.head())
- Чтение данных из Excel файла:
# Чтение данных из Excel файла data = pd.read_excel('data.xlsx') # Вывод первых нескольких строк датафрейма print(data.head())
- Чтение данных из SQL базы данных:
from sqlalchemy import create_engine # Создание подключения к базе данных engine = create_engine('sqlite:///database.db') # Чтение данных с помощью SQL запроса query = "SELECT * FROM table_name" data = pd.read_sql(query, engine) # Вывод первых нескольких строк датафрейма print(data.head())
Запись данных:
- Запись данных в CSV или Exсel файл:
# Создание датафрейма data = pd.DataFrame(< 'name': ['Alice', 'Bob', 'Charlie'], 'age': [25, 30, 22] >) # Запись в CSV файл (или Exсel, нужно будет поменять расширение ниже) data.to_csv('output.csv', index=False)
- Запись данных в SQL базу данных:
import pandas as pd from sqlalchemy import create_engine # Создание датафрейма data = pd.DataFrame(< 'name': ['Alice', 'Bob', 'Charlie'], 'age': [25, 30, 22] >) # Создание подключения к базе данных engine = create_engine('sqlite:///new_database.db') # Запись данных в базу данных data.to_sql('new_table', engine, index=False, if_exists='replace')
Доступ по индексу в DataFrame
Для поиска данных в библиотеке Pandas используются два метода: .loc и .iloc . Рассмотрим их функциональность и применение.
Метод .loc:
Метод .loc предоставляет доступ к данным по заданному имени строки (индексу) в DataFrame. Рассмотрим пример с набором данных о скорости и ядовитости нескольких видов змей:
data = index = ['cobra', 'viper', 'sidewinder'] df = pd.DataFrame(data, index=index) # Вывод датафрейма print(df)
Используя метод .loc , мы можем получить информацию о конкретном виде змеи, например, гадюке (viper):
# Получение данных о гадюке (viper) viper_data = df.loc['viper'] print(viper_data)
Метод .iloc:
Метод .iloc позволяет осуществлять доступ к данным по порядковому номеру строки в DataFrame. Рассмотрим пример с набором данных, имеющим числовые индексы:
mydict = [, , ] df = pd.DataFrame(mydict) # Вывод датафрейма print(df)
a b c d 0 1 2 3 4 1 100 200 300 400 2 1000 2000 3000 4000
Используя метод .iloc , можно получить данные из первой строки с индексом 0:
first_row = df.iloc[0] first_row
Читайте также Что нужно знать, чтобы стать дата-сайентистом?
Группировка и агрегирование данных
Для этого используется метод .groupby , он позволяет анализировать отдельные группы данных и сравнивать показатели. Например, у нас есть несколько обучающих курсов, информация о которых хранится в одной таблице. Нужно проанализировать, какой доход приносит каждый из них:
Используем .groupby и указываем название колонки title, на основе которой Pandas объединит все данные. После этого используем метод .agregate – он поможет провести математические вычисления, то есть суммировать стоимость внутри каждой группы.
import pandas as pd # Создание DataFrame с данными о курсах data = < 'title': ['Курс A', 'Курс B', 'Курс C', 'Курс D', 'Курс E'], 'income': [100, 150, 200, 120, 180] >df = pd.DataFrame(data) # Группировка данных по названию курса и агрегирование дохода grouped = df.groupby('title', as_index=False).aggregate() grouped
Обратите внимание на as_index=False , эта часть кода отвечает за то, чтобы сохранить числовые индексы в результатах группировки и вычисления.
Сводные таблицы в Pandas
Их используют для обобщения информации, собранной об объекте исследования. Когда исходных данных много и все они разного типа, составление таблиц помогает упорядочить информацию. Чтобы создавать на Python сводные таблицы, тоже используют библиотеку Pandas, а именно — метод .pivot_table .
Для примера возьмем условный набор данных с простыми категориями one / two, small / large и числовыми значениями. В столбце A две категории foo / bar складываются в слово foobar — текст, который используется в программировании для условного обозначения. В этом случае он указывает, что мы делим данные на две группы по неопределенному признаку.
df = pd.DataFrame() df
Результат выполнения кода:
С помощью метода .pivot_table преобразуем эти данные в таблицу, а в скобках прописываем условия.
table = pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C'], aggfunc=np.sum) table
Мы разбиваем данные на две категории: bar и foo, в каждой из них будут подгруппы со значениями one и two, которые в свою очередь делятся на small и large. В сводной таблице мы вычисляем, сколько объектов будет в каждой группе. Для этого используем методы values, index, columns и aggfunc:
- values — метод для агрегации, объединяет элементы в одну систему;
- index и columns — методы, отвечающие за группировку столбцов;
- aggfunc — метод, который передает список функций, необходимых для расчета.
Визуализация данных в Pandas
Дата-аналитики составляют наглядные графики с помощью Pandas и библиотеки Matplotlib. В этой связке Pandas отвечает за вычислительную часть работы, а вспомогательная библиотека «создает» картинку.
Посмотрим на данные о продажах в одной из компаний:
Число покупок на одного покупателя | Количество покупателей |
---|---|
7000 | 4 |
3755 | 6 |
2523 | 13 |
541 | 16 |
251 | 21 |
1 | 31 |
В таблице видно, что одни пользователи совершили уже более 7 000 покупок, а некоторые — сделали первую. Чтобы увидеть подробную картину, составляем график sns.distplot. На горизонтальной оси будет отображаться число покупок на одного покупателя, а на вертикальной — количество покупателей, которые совершили именно столько покупок в этой компании. Так по графику можно определить, что самой многочисленной оказалась группа клиентов, которая совершила всего несколько покупок, а группа постоянных клиентов немногочисленная.
import seaborn as sns import matplotlib.pyplot as plt # Создание данных purchase_counts = [7000, 3755, 2523, 541, 251, 1] customer_counts = [4, 6, 13, 16, 21, 31] # Создание графика sns.set(style="whitegrid") sns.distplot(purchase_counts, bins=20, kde=False, hist_kws=) plt.xlabel('Число покупок на одного покупателя') plt.ylabel('Количество покупателей') plt.title('Распределение числа покупок') plt.show()
distplot — это график, который визуализирует гистограммы, то есть распределяет данные по столбцам. Каждому столбцу соответствует доля количества объектов в данной группе. Также distplot показывает плотность распределения — плавный линейный график, в котором самая высокая точка указывает на наибольшее количество объектов.
Кроме этого, в Pandas есть другие виды графиков:
- kdeplot — график плотности распределения, который останется, если убрать гистограммы из distplot;
- jointplot — график, показывающий распределение данных между двумя переменными. Каждая строка из набора данных в исходном файле отображается на графике как точка внутри системы координат. У точек на графике jointplot будет два заданных значения: одно по оси X, другое по оси Y.
Например, можно отследить взаимосвязь между тем, сколько минут посетитель проводит в торговом центре и сколько магазинов успевает посетить за это время: кто-то за 30 минут успеет зайти в 5 бутиков, а кто-то обойдет 16. При этом каждый посетитель на графике будет отображаться отдельной точкой.
Аналитик данных
Аналитики влияют на рост бизнеса. Они выясняют, какой товар и в какое время больше покупают. Считают юнит-экономику. Оценивают окупаемость рекламной кампании. Поэтому компании ищут и переманивают таких специалистов.
Статьи по теме:
Разбираемся, почему эти профессии не стоит путать
Отвечает Мария Жарова, эксперт по Python и математике для Data Science, ментор одного из проектов на курсе по Data Science.
Pandas: обзор библиотеки для Python
Библиотека Pandas входит в топ-5 самых востребованных навыков для вакансий в области data science.
Михаил Елизаров
Автор статьи
10 ноября 2022 в 18:26
Библиотека Pandas — «рабочая лошадка» аналитика данных. Она входит в топ-5 самых востребованных навыков для вакансий в области data science.
Рассказываем в статье, что такое Pandas для Python, как его установить, пользоваться и почему это классная штука.
Аналитик данных: новая работа через 5 месяцев
Получится, даже если у вас нет опыта в IT
Что такое Pandas для Python
Библиотеку используют для анализа и обработки табличных данных. Pandas — это как Excel, но мощнее. В Pandas можно спокойно работать с данными объемом в миллионы строк.
Поэтому на курсе Skypro «Аналитик данных» студентам дают основы Python. За несколько месяцев можно освоить базовые навыки, чтобы обрабатывать данные быстрее и качественнее. А еще с помощью знаний Python можно создавать визуализации, чтобы данные подтягивались туда из таблиц и обновлялись автоматически.
У Pandas открытый исходный код и подробная документация.
Структуры классов
Есть два главных класса библиотеки: Series и DataFrame.
Класс Series
Series — одномерный индексированный массив, который способен хранить данные любого типа. Номер записи в массиве называется индексом.
Пример создания Series:
Класс DataFrame
DataFrame — таблица с разными типами столбцов, то есть двумерная структура данных.
Пример создания DataFrame:
Как установить Pandas
Установите набор программ Anaconda — в него входит Python вместе с Pandas и другими полезными библиотеками.
- Скачайте установщик с сайта Anaconda.
- Откройте файл и следуйте инструкциям. Не забудьте поставить галочку в опции «Add Anaconda to my PATH environment variable».
- Перезагрузите компьютер.
- Откройте anaconda navigator и запустите jupyter notebook.
После этого импортируйте Pandas командой import pandas as pd.
Основная функциональность
Методы классов Series и DataFrame позволяют считать сводные статистики: среднюю, медиану, сумму и другие.
Пример:
Загружаем данные с характеристиками алмазов.
Считаем среднее и стандартное отклонение цены.
Для статистик по категориям используйте группировку.
Пример:
Посмотрим средние значения цены и размеров по разным типам огранки из колонки cut.
Обратите внимание, как отличается цена
Для двух групп используйте сводные таблицы.
Пример:
Узнаем среднюю цену алмазов по качеству обработки и цвету.
При помощи Pandas можно визуализировать данные. Для создания графиков используйте метод plot с параметром kind, который отвечает за тип визуализации.
Некоторые виды графиков:
- линейный — вызывается по умолчанию;
- столбчатый;
- гистограмма;
- боксплот;
- диаграмма рассеяния.
Посмотрим, как цена зависит от размера, построив диаграмму рассеяния.
Примеры использования в аналитике
Продолжим изучать данные об алмазах. Постараемся ответить на вопрос, что влияет на цену. Для работы понадобятся библиотеки Seaborn и Matplotlib, которые вы установили вместе с Anaconda.
Загрузим таблицу и посмотрим на ее начало, используя команду head.
Shape показывает количество строк (53 940) и столбцов (10):
С помощью метода info посмотрим на типы данных и количество заполненных значений в колонках.
Сolor, cut и clarity — категориальные переменные. Остальные — вещественные (числа).
Проанализируем их по отдельности.
Анализ категориальных переменных
Посмотрим на уникальные значения по каждой колонке с помощью команды value_counts. Вызовем ее из цикла.
for i in ['cut', 'clarity', 'color']: print(df[i].value_counts())
Для визуализации используем боксплоты, которые показывают распределение цены по каждой из категорий.
Вывод — исходя из графиков, дороже всего стоят алмазы с параметрами:
- Premium в колонке cut.
- VS1, VS2, SI1, SI2, I1 в колонке clarity.
- H, I или J в колонке color.
Анализ вещественных переменных
Статистику по числовым столбцам получим командой describe.
Посмотрим, как с ними взаимодействует стоимость камней, с помощью диаграмм рассеяния.
Вывод — цена сильнее всего зависит от переменных carat и x.
Мы узнали, что колонки carat, x, cut, clarity и color влияют на стоимость алмаза. Дальше можно построить модель для предсказания цены в зависимости от этих переменных.
Чтобы узнать, как это правильно сделать, записывайтесь на курс «Аналитик данных». За пять месяцев вы научитесь работать со статистикой, в Python, SQL и Excel. Наставники на курсе — аналитики из «Сбера», «Яндекса» и других крупных компаний. В конце курса специалисты центра карьеры помогут составить грамотное резюме и найти первую работу.
10 приемов Python Pandas, которые сделают вашу работу более эффективной
Pandas — это широко используемый пакет Python для структурированных данных. Существует много хороших учебных пособий на данную тематику, но здесь мы бы хотели раскрыть несколько интересных приемов, которые, вероятно, еще пока неизвестны читателю, но могут оказаться крайне полезными.
read_csv
Все знают эту команду. Но если данные, которые вы пытаетесь прочитать, слишком большие, попробуйте добавить команду nrows = 5 , чтобы прочитать сначала небольшую часть данных перед загрузкой всей таблицы. В этом случае вам удастся избежать ситуации выбора неверного разделителя (не всегда в данных есть разделение в виде запятой).
(Или вы можете использовать команду ‘head’ в linux для проверки первых 5 строк в любом текстовом файле: head -c 5 data.txt )
Затем вы можете извлечь список столбцов, используя df.columns.tolist() , а затем добавить команду usecols = [‘c1’, ‘c2’,…], чтобы извлечь только нужные вам столбцы. Кроме того, если вы знаете типы данных определенных столбцов, вы можете добавить dtype = для более быстрой загрузки. Еще одно преимущество этой команды в том, что если у вас есть столбец, который содержит как строки, так и числа, рекомендуется объявить его тип строковым, чтобы не возникало ошибок при попытке объединить таблицы, используя этот столбец в качестве ключа.
select_dtypes
Если предварительная обработка данных должна выполняться в Python, то эта команда сэкономит ваше время. После чтения из таблицы типами данных по умолчанию для каждого столбца могут быть bool, int64, float64, object, category, timedelta64 или datetime64. Вы можете сначала проверить распределение с помощью
df.dtypes.value_counts()
чтобы узнать все возможные типы данных вашего фрейма, затем используйте
df.select_dtypes(include=[‘float64’, ‘int64’])
чтобы выбрать субфрейм только с числовыми характеристиками.
сopy
Это важная команда. Если вы сделаете:
import pandas as pd
df1 = pd.DataFrame(< ‘a’:[0,0,0], ‘b’: [1,1,1]>)
df2 = df1
df2[‘a’] = df2[‘a’] + 1
df1.head()
Вы обнаружите, что df1 изменен. Это потому, что df2 = df1 не делает копию df1 и присваивает ее df2, а устанавливает указатель, указывающий на df1. Таким образом, любые изменения в df2 приведут к изменениям в df1. Чтобы это исправить, вы можете сделать либо:
df2 = df1.copy ()
from copy import deepcopy
df2 = deepcopy(df1)
map
Это классная команда для простого преобразования данных. Сначала вы определяете словарь, в котором «ключами» являются старые значения, а «значениями» являются новые значения.
level_map =
df[‘c_level’] = df[‘c’].map(level_map)
Например: True, False до 1, 0 (для моделирования); определение уровней; определяемые пользователем лексические кодировки.
apply or not apply?
Если нужно создать новый столбец с несколькими другими столбцами в качестве входных данных, функция apply была бы весьма полезна.
def rule(x, y):
if x == ‘high’ and y > 10:
return 1
else:
return 0
df = pd.DataFrame(< 'c1':[ 'high' ,'high', 'low', 'low'], 'c2': [0, 23, 17, 4]>)
df['new'] = df.apply(lambda x: rule(x['c1'], x['c2']), axis = 1)
df.head()
В приведенных выше кодах мы определяем функцию с двумя входными переменными и используем функцию apply, чтобы применить ее к столбцам ‘c1’ и ‘c2’.
но проблема «apply» заключается в том, что иногда она занимает очень много времени.
Скажем, если вы хотите рассчитать максимум из двух столбцов «c1» и «c2», конечно, вы можете применить данную команду
df[‘maximum’] = df.apply(lambda x: max(x[‘c1’], x[‘c2’]), axis = 1)
но это будет медленнее, нежели:
df[‘maximum’] = df[[‘c1’,’c2']].max(axis =1)
Вывод: не используйте команду apply, если вы можете выполнить ту же работу используя другие функции (они часто быстрее). Например, если вы хотите округлить столбец ‘c’ до целых чисел, выполните округление (df [‘c’], 0) вместо использования функции apply.
value counts
Это команда для проверки распределения значений. Например, если вы хотите проверить возможные значения и частоту для каждого отдельного значения в столбце «c», вы можете применить
df[‘c’].value_counts()
Есть несколько полезных приемов / функций:
A. normalize = True : если вы хотите проверить частоту вместо подсчетов.
B. dropna = False : если вы хотите включить пропущенные значения в статистику.
C. sort = False : показать статистику, отсортированную по значениям, а не по количеству.
D. df[‘c].value_counts().reset_index().: если вы хотите преобразовать таблицу статистики в датафрейм Pandas и управлять ими.
количество пропущенных значений
При построении моделей может потребоваться исключить строку со слишком большим количеством пропущенных значений / строки со всеми пропущенными значениями. Вы можете использовать .isnull () и .sum () для подсчета количества пропущенных значений в указанных столбцах.
import pandas as pd
import numpy as np
df = pd.DataFrame(< ‘id’: [1,2,3], ‘c1’:[0,0,np.nan], ‘c2’: [np.nan,1,1]>)
df = df[[‘id’, ‘c1’, ‘c2’]]
df[‘num_nulls’] = df[[‘c1’, ‘c2’]].isnull().sum(axis=1)
df.head()
выбрать строки с конкретными идентификаторами
В SQL мы можем сделать это, используя SELECT * FROM… WHERE ID в («A001», «C022»,…), чтобы получить записи с конкретными идентификаторами. Если вы хотите сделать то же самое с pandas, вы можете использовать:
df_filter = df ['ID']. isin (['A001', 'C022', . ])
df [df_filter]
Percentile groups
Допустим, у вас есть столбец с числовыми значениями, и вы хотите классифицировать значения в этом столбце по группам, скажем, топ 5% в группу 1, 5–20% в группу 2, 20–50% в группу 3, нижние 50% в группу 4. Конечно, вы можете сделать это с помощью pandas.cut, но мы бы хотели представить другую функцию:
import numpy as np
cut_points = [np.percentile(df[‘c’], i) for i in [50, 80, 95]]
df[‘group’] = 1
for i in range(3):
df[‘group’] = df[‘group’] + (df[‘c’] < cut_points[i])
# or Которая быстро запускается (не применяется функция apply).to_csv
Опять-таки, это команда, которую используют все. Отметим пару полезных приемов. Первый:print(df[:5].to_csv())Вы можете использовать эту команду, чтобы напечатать первые пять строк того, что будет записано непосредственно в файл.
Еще один прием касается смешанных вместе целых чисел и пропущенных значений. Если столбец содержит как пропущенные значения, так и целые числа, тип данных по-прежнему будет float, а не int. Когда вы экспортируете таблицу, вы можете добавить float_format = '%. 0f', чтобы округлить все числа типа float до целых чисел. Используйте этот прием, если вам нужны только целочисленные выходные данные для всех столбцов – так вы избавитесь от всех назойливых нулей ‘.0’ .