test

Форк
0
/
Pandas_pr3.ipynb 
974 строки · 35.0 Кб
1
{
2
  "cells": [
3
    {
4
      "cell_type": "markdown",
5
      "metadata": {
6
        "id": "nPCp6G1zI-Ew"
7
      },
8
      "source": [
9
        "# Работа с Pandas\n",
10
        "\n",
11
        "\n",
12
        "## Series\n",
13
        "\n",
14
        "`Series` - это одна из структур данных библиотеки `pandas`. Она представляет собой что-то вроде словаря, однако, является упорядоченной.\n",
15
        "\n",
16
        "Создадим какой-нибудь список, а затем получим на его основе объект `Series`:"
17
      ]
18
    },
19
    {
20
      "cell_type": "code",
21
      "execution_count": 1,
22
      "metadata": {
23
        "id": "UUMvqVhwI-Ex"
24
      },
25
      "outputs": [],
26
      "source": [
27
        "import pandas as pd"
28
      ]
29
    },
30
    {
31
      "cell_type": "code",
32
      "execution_count": null,
33
      "metadata": {
34
        "id": "r7BIt-kQI-E1"
35
      },
36
      "outputs": [],
37
      "source": [
38
        "a = [1, 3, 5, 7, 2]\n",
39
        "\n",
40
        "b = pd.Series(a)\n",
41
        "\n",
42
        "print(b)"
43
      ]
44
    },
45
    {
46
      "cell_type": "markdown",
47
      "metadata": {
48
        "id": "RNvSFF_NI-E6"
49
      },
50
      "source": [
51
        "В результате такой операции получается объект `Series`, содержащий элементы из списка `a`. Здесь справа располагаются элементы из `a`, а слева - их индексы. Поскольку индексы для этих элементов мы явно не указали, используются стандартные.\n",
52
        "\n",
53
        "Индексы можно также указать явно, для этого нужно подать в качестве аргумента `index` список из индексов. Данный список должен быть той же длины, что и список `a`.\n"
54
      ]
55
    },
56
    {
57
      "cell_type": "markdown",
58
      "metadata": {
59
        "id": "akKQ3IiUI-FA"
60
      },
61
      "source": [
62
        "Индексы можно задать сразу, а можно и изменить позже:"
63
      ]
64
    },
65
    {
66
      "cell_type": "code",
67
      "execution_count": null,
68
      "metadata": {
69
        "id": "ruk5GAE3I-FB"
70
      },
71
      "outputs": [],
72
      "source": [
73
        "b.index = [\"a\", \"b\", \"c\", \"d\", \"e\"]\n",
74
        "\n",
75
        "print(b)"
76
      ]
77
    },
78
    {
79
      "cell_type": "markdown",
80
      "metadata": {
81
        "id": "YxxTvVIFI-FR"
82
      },
83
      "source": [
84
        "Индексы в `Series` не обязаны быть уникальными:"
85
      ]
86
    },
87
    {
88
      "cell_type": "code",
89
      "execution_count": null,
90
      "metadata": {
91
        "id": "65AeCMUbI-FS"
92
      },
93
      "outputs": [],
94
      "source": [
95
        "d = pd.Series(a, index=[0, 1, 0, 1, 0])\n",
96
        "\n",
97
        "print(d)"
98
      ]
99
    },
100
    {
101
      "cell_type": "markdown",
102
      "metadata": {
103
        "id": "G5Z7PCwmI-GK"
104
      },
105
      "source": [
106
        "### Добавление и удаление данных в Series\n",
107
        "\n",
108
        "С помощью метода `.append` мы можем добавлять к одному массиву `Series` другой:"
109
      ]
110
    },
111
    {
112
      "cell_type": "code",
113
      "execution_count": null,
114
      "metadata": {
115
        "id": "sHq5bhAII-GL"
116
      },
117
      "outputs": [],
118
      "source": [
119
        "g = d.append(b)\n",
120
        "\n",
121
        "print(g)"
122
      ]
123
    },
124
    {
125
      "cell_type": "markdown",
126
      "metadata": {
127
        "id": "1OnEv778I-GO"
128
      },
129
      "source": [
130
        "С помощью метода `.drop` мы можем удалять из массива элементы с определёнными индексами. Эти индексы мы и подаём в метод в виде списка:"
131
      ]
132
    },
133
    {
134
      "cell_type": "code",
135
      "execution_count": null,
136
      "metadata": {
137
        "id": "n_TqKZG_I-GP"
138
      },
139
      "outputs": [],
140
      "source": [
141
        "h = g.drop([0, \"d\"])\n",
142
        "\n",
143
        "print(h)"
144
      ]
145
    },
146
    {
147
      "cell_type": "markdown",
148
      "metadata": {
149
        "id": "B9GSACSLI-GR"
150
      },
151
      "source": [
152
        "Обратите внимание, что эти методы, в отличие от аналогичных методов из стандартных библиотек питона, не изменяют исходный массив, но возвращают новый.\n",
153
        "\n",
154
        "### Запись и чтение массивов Series из файла\n",
155
        "\n",
156
        "\n",
157
        "Для записи массивов `Series` в файлы используется формат файлов под названием `pickle`. Этот формат позволяет полностью сохранять питоновские объекты, а затем загружать их в неизменном виде.\n",
158
        "\n",
159
        "Для записи массива `Series` в файл используется метод `.to_pickle`, а для чтения - функция `np.read_pickle`:"
160
      ]
161
    },
162
    {
163
      "cell_type": "code",
164
      "execution_count": 13,
165
      "metadata": {
166
        "id": "ZTrPh3ELI-GS"
167
      },
168
      "outputs": [],
169
      "source": [
170
        "h.to_pickle(\"h.pkl\")"
171
      ]
172
    },
173
    {
174
      "cell_type": "code",
175
      "execution_count": null,
176
      "metadata": {
177
        "id": "ZYirazZHI-GV"
178
      },
179
      "outputs": [],
180
      "source": [
181
        "h1 = pd.read_pickle(\"h.pkl\")\n",
182
        "\n",
183
        "print(h1)"
184
      ]
185
    },
186
    {
187
      "cell_type": "markdown",
188
      "metadata": {
189
        "id": "VtiWsjwkI-GX"
190
      },
191
      "source": [
192
        "## DataFrame\n",
193
        "\n",
194
        "`DataFrame` - двумерная структура данных из библиотеки `pandas`, позволяющая удобно работать с таблицами.\n",
195
        "\n",
196
        "Самый простой способ задать `DataFrame` - с помощью словаря, в котором каждый ключ отвечает за столбец, а соответствующее значение - это список из элементов данного столбца. Эти списки должны иметь одинаковую длину."
197
      ]
198
    },
199
    {
200
      "cell_type": "code",
201
      "execution_count": null,
202
      "metadata": {
203
        "id": "Do-NbZz3I-GY"
204
      },
205
      "outputs": [],
206
      "source": [
207
        "a = {\n",
208
        "    \"col1\": [1, 2, 4, 5, 6, 7, 8],\n",
209
        "    \"col2\": [\"a\", \"c\", \"e\", \"g\", \"z\", \"x\", \"y\"]\n",
210
        "}\n",
211
        "\n",
212
        "b = pd.DataFrame(a)\n",
213
        "\n",
214
        "b"
215
      ]
216
    },
217
    {
218
      "cell_type": "markdown",
219
      "metadata": {
220
        "id": "5r6rUlqxI-Gb"
221
      },
222
      "source": [
223
        "С помощью атрибута `.shape` можно посмотреть форму массива `DataFrame`. Атрибут `.columns` содержит массив из столбцов, а `.index`, как и ранее, содержит массив индексов."
224
      ]
225
    },
226
    {
227
      "cell_type": "code",
228
      "execution_count": null,
229
      "metadata": {
230
        "id": "d-BlBVFnI-Gc"
231
      },
232
      "outputs": [],
233
      "source": [
234
        "print(\"Форма b: {}\".format(b.shape))\n",
235
        "\n",
236
        "print(\"Столбцы b: {}\".format(b.columns))\n",
237
        "\n",
238
        "print(\"Индексы b: {}\".format(b.index))"
239
      ]
240
    },
241
    {
242
      "cell_type": "markdown",
243
      "metadata": {
244
        "id": "pgn1tqBbI-Gf"
245
      },
246
      "source": [
247
        "Общую информацию о массиве можно запросить с помощью метода `.info`. Нам вернётся информация об индексах и столбцах данного массива, о том, какие типы данных хранятся в каждом из столбцов, а также информация о том, сколько памяти выделено под данный массив."
248
      ]
249
    },
250
    {
251
      "cell_type": "code",
252
      "execution_count": null,
253
      "metadata": {
254
        "id": "6kE3cFoPI-Gg"
255
      },
256
      "outputs": [],
257
      "source": [
258
        "b.info()"
259
      ]
260
    },
261
    {
262
      "cell_type": "markdown",
263
      "metadata": {
264
        "id": "IKpjQKm0I-Gj"
265
      },
266
      "source": [
267
        "С помощью метода `.describe` можно получить некоторые статистические характеристики по столбцам с числовыми значениями: среднее значение, среднее квадратическое отклонение, максимум, минимум, квантили и пр."
268
      ]
269
    },
270
    {
271
      "cell_type": "code",
272
      "execution_count": null,
273
      "metadata": {
274
        "id": "pDzeYsuQI-Gj"
275
      },
276
      "outputs": [],
277
      "source": [
278
        "b.describe()"
279
      ]
280
    },
281
    {
282
      "cell_type": "markdown",
283
      "metadata": {
284
        "id": "F4El81QKI-HS"
285
      },
286
      "source": [
287
        "### Случайный выбор значений из DataFrame\n",
288
        "\n",
289
        "Случайный выбор строк из массива `DataFrame` производится с помощью метода `.sample`. Вот несколько его важных параметров:\n",
290
        "\n",
291
        "* `frac` - какую долю от общего числа строк нужно вернуть (число от 0 до 1)\n",
292
        "* `n` - сколько строк нужно вернуть (число от 0 до числа строк в массиве)\n",
293
        "* `replace` - индикатор того, производится ли выбор _с возвращением_, т.е. с возможным повторением строк в выборке, или _без возвращения_ (`True` или `False`)\n",
294
        "\n",
295
        "Нельзя использовать параметры `frac` и `n` одновременно, нужно выбрать какой-то один."
296
      ]
297
    },
298
    {
299
      "cell_type": "code",
300
      "execution_count": null,
301
      "metadata": {
302
        "id": "U2roX2B-I-HT"
303
      },
304
      "outputs": [],
305
      "source": [
306
        "b.sample(frac=0.5, replace=True)"
307
      ]
308
    },
309
    {
310
      "cell_type": "markdown",
311
      "metadata": {
312
        "id": "FsUnA0MdI-HZ"
313
      },
314
      "source": [
315
        "Если требуется просто перемешать всю выборку, это также можно выполнить с помощью метода `.sample`, передав в него параметр `frac=1`.\n",
316
        "\n",
317
        "### Запись и чтение DataFrame из файлов\n",
318
        "\n",
319
        "Для хранения таблиц широко распространён формат файлов с расширением `.csv`.\n",
320
        "\n",
321
        "Сохранить массив в файл можно с помощью метода `.to_csv`. Вот несколько важных параметров этого метода:\n",
322
        "\n",
323
        "* `sep` - символ, который нужно использовать для разделения значения столбцов между собой. По умолчанию это `\",\"`, но можно также использовать `\";\"`, `\"\\t\"` и др.\n",
324
        "* `index` - булево значение, индикатор того, нужно ли в файл сохранить также столбец индексов.\n"
325
      ]
326
    },
327
    {
328
      "cell_type": "code",
329
      "execution_count": 20,
330
      "metadata": {
331
        "id": "RYMORR5TI-Hb"
332
      },
333
      "outputs": [],
334
      "source": [
335
        "b.to_csv(\"test.csv\", sep=\";\", index=False)"
336
      ]
337
    },
338
    {
339
      "cell_type": "markdown",
340
      "metadata": {
341
        "id": "IyBxeXaVI-Hm"
342
      },
343
      "source": [
344
        "Прочитать массив из файла можно с помощью функции `pd.read_csv`. Здесь также можно указать разделитель столбцов в параметре `sep`."
345
      ]
346
    },
347
    {
348
      "cell_type": "code",
349
      "execution_count": null,
350
      "metadata": {
351
        "id": "Lk_wWrT2I-Hm"
352
      },
353
      "outputs": [],
354
      "source": [
355
        "b1 = pd.read_csv(\"test.csv\", sep=\";\")\n",
356
        "\n",
357
        "b1"
358
      ]
359
    },
360
    {
361
      "cell_type": "markdown",
362
      "metadata": {
363
        "id": "eFmm9O6UI-Hp"
364
      },
365
      "source": [
366
        "У данных команд для сохранения и чтения таблиц есть множество других важных и полезных параметров, поэтому рекомендуется также изучить их документацию: [to_csv](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_csv.html), [read_csv](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html).\n",
367
        "\n",
368
        "В `pandas` также имеются аналогичные команды для сохранения и записи таблиц как `excel` и `pickle`."
369
      ]
370
    },
371
    {
372
      "cell_type": "markdown",
373
      "metadata": {
374
        "id": "yiL5JLa-I-Hp"
375
      },
376
      "source": [
377
        "## Работа с данными в Pandas\n",
378
        "\n",
379
        "### Слияние данных\n",
380
        "\n",
381
        "Рассмотрим следующий пример. Допустим, что мы работаем с небольшим отделом книжного магазина, в котором продаётся классическая литература. Наша задача - систематизировать ассортимент отдела.\n",
382
        "\n",
383
        "У нас есть таблица `authors`, содержащая данные об авторах: их идентификаторы (`author_id`) и имена (`author_name`):"
384
      ]
385
    },
386
    {
387
      "cell_type": "code",
388
      "execution_count": null,
389
      "metadata": {
390
        "id": "ol2u5eVDI-Hq"
391
      },
392
      "outputs": [],
393
      "source": [
394
        "authors = pd.DataFrame({\n",
395
        "    'author_id': [1, 2, 3],\n",
396
        "    'author_name': ['Пушкин', 'Толстой', 'Достоевский'],\n",
397
        "})\n",
398
        "\n",
399
        "authors"
400
      ]
401
    },
402
    {
403
      "cell_type": "markdown",
404
      "metadata": {
405
        "id": "6-IVLnBvI-Hs"
406
      },
407
      "source": [
408
        "Кроме того, у нас есть таблица `books`, содержащая информацию о книгах этих авторов. В этой таблице также есть колонка `author_id`, а также колонка `book_title`, содержащая название книги:"
409
      ]
410
    },
411
    {
412
      "cell_type": "code",
413
      "execution_count": null,
414
      "metadata": {
415
        "id": "ESCfC0eaI-Hs"
416
      },
417
      "outputs": [],
418
      "source": [
419
        "books = pd.DataFrame({\n",
420
        "    'author_id': [2, 3, 3, 4],\n",
421
        "    'book_title': ['Война и мир', 'Идиот', 'Преступление и наказание',\n",
422
        "                   'Отцы и дети'],\n",
423
        "})\n",
424
        "\n",
425
        "books"
426
      ]
427
    },
428
    {
429
      "cell_type": "markdown",
430
      "metadata": {
431
        "id": "YrsRPVSEI-Hv"
432
      },
433
      "source": [
434
        "Что делать, если мы, например, захотим сопоставить названия книг именам их авторов? Для этого используется функция `pd.merge`: в эту функцию помещаются те таблицы, которые мы хотим соединить, а также несколько других важных аргументов:\n",
435
        "\n",
436
        "* `on` - параметр, отвечающий за то, какой столбец мы будем использовать для слияния,\n",
437
        "* `how` - каким образом производить слияние.\n",
438
        "\n",
439
        "Опишем подробнее, какие значения может принимать параметр `how`:\n",
440
        "\n",
441
        "* `\"inner\"` - внутреннее слияние. В этом случае в слиянии участвуют только те строки, которые присутствуют в обоих таблицах,\n",
442
        "* `\"left\"` - в слиянии участвуют все строки из левой таблицы,\n",
443
        "* `\"right\"` - то же самое, но для правой таблицы,\n",
444
        "* `\"outer\"` - внешнее слияние, соединяются все строки как из левой, так и из правой таблицы."
445
      ]
446
    },
447
    {
448
      "cell_type": "code",
449
      "execution_count": null,
450
      "metadata": {
451
        "id": "8n2gin-nI-Hw"
452
      },
453
      "outputs": [],
454
      "source": [
455
        "pd.merge(authors, books, on='author_id', how='inner')"
456
      ]
457
    },
458
    {
459
      "cell_type": "markdown",
460
      "metadata": {
461
        "id": "bVPmcn37I-Hy"
462
      },
463
      "source": [
464
        "Если мы выбираем `\"left\"`, `\"right\"` или `\"outer\"`, может случиться так, что строку из одной таблицы будет невозможно соединить со второй. Например, мы видим, что в нашей таблице `books` нет произведений Пушкина (его `id` равен 1). В свою очередь, в таблице `books` есть книга, для которой `author_id` равен 4, хотя, в таблице `authors` нет записи с таким `author_id`. Рассмотрим внешнее слияние этих таблиц:"
465
      ]
466
    },
467
    {
468
      "cell_type": "code",
469
      "execution_count": null,
470
      "metadata": {
471
        "id": "P9E4mInBI-Hz"
472
      },
473
      "outputs": [],
474
      "source": [
475
        "merged_df = pd.merge(authors, books, on='author_id', how='outer')\n",
476
        "\n",
477
        "merged_df"
478
      ]
479
    },
480
    {
481
      "cell_type": "markdown",
482
      "metadata": {
483
        "id": "Af0I2qVKI-H3"
484
      },
485
      "source": [
486
        "Как мы видим, в получившейся таблице присутствуют пропущенные значения (`NaN`).\n",
487
        "\n",
488
        "### Работа с пропущенными данными\n",
489
        "\n",
490
        "Пропущенные значения в `Series` или `DataFrame` можно получить с помощью метода `.isnull`. Наоборот, все имеющиеся непустые значения можно получить с помощью метода `.notnull`:"
491
      ]
492
    },
493
    {
494
      "cell_type": "code",
495
      "execution_count": null,
496
      "metadata": {
497
        "id": "PIVEZX7sI-H3"
498
      },
499
      "outputs": [],
500
      "source": [
501
        "merged_df[merged_df[\"author_name\"].isnull()]"
502
      ]
503
    },
504
    {
505
      "cell_type": "code",
506
      "execution_count": null,
507
      "metadata": {
508
        "id": "F0MaLqu1I-H5"
509
      },
510
      "outputs": [],
511
      "source": [
512
        "merged_df[merged_df[\"author_name\"].notnull()]"
513
      ]
514
    },
515
    {
516
      "cell_type": "markdown",
517
      "metadata": {
518
        "id": "pNq0X7x-I-H7"
519
      },
520
      "source": [
521
        "Заполнить пропущенные значения каким-то своим значением можно с помощью метода `.fillna()`:"
522
      ]
523
    },
524
    {
525
      "cell_type": "code",
526
      "execution_count": null,
527
      "metadata": {
528
        "id": "76FEe8XjI-H8"
529
      },
530
      "outputs": [],
531
      "source": [
532
        "merged_df[\"author_name\"] = merged_df[\"author_name\"].fillna(\"unknown\")\n",
533
        "\n",
534
        "merged_df"
535
      ]
536
    },
537
    {
538
      "cell_type": "markdown",
539
      "metadata": {
540
        "id": "nVrQXD-II-H-"
541
      },
542
      "source": [
543
        "### Добавление столбцов в `DataFrame`.\n",
544
        "\n",
545
        "Допустим, каждая из наших книг имеется в единственном экземпляре. Мы хотели бы создать в таблице `merged_df` столбец `quantity`, который бы содержал количество экземпляров каждой книги.\n",
546
        "\n",
547
        "Создание нового столбца в таблице `DataFrame` происходит аналогично созданию нового значения в словаре `dict`. Достаточно просто объявить значение `merged_df[\"quantity\"]`. Если подать в это значение какое-нибудь число или строку, то все значения в данном столбце приравняются к этому числу или строке. Также можно подать сюда список, тогда значения из этого списка поступят в соответствующие строки этого столбца. В этом случае длина списка обязана совпадать с числом строк таблицы.\n",
548
        "\n",
549
        "Итак, выберем все строки с непустым значением поля `book_title`, и для них запишем в столбец `quantity` число 1. Это можно сделать с помощью атрибута `.loc`:"
550
      ]
551
    },
552
    {
553
      "cell_type": "code",
554
      "execution_count": null,
555
      "metadata": {
556
        "id": "qMczv7OTI-H-"
557
      },
558
      "outputs": [],
559
      "source": [
560
        "merged_df.loc[merged_df[\"book_title\"].notnull(), \"quantity\"] = 1\n",
561
        "\n",
562
        "merged_df"
563
      ]
564
    },
565
    {
566
      "cell_type": "markdown",
567
      "metadata": {
568
        "id": "AOBt9xicI-IA"
569
      },
570
      "source": [
571
        "Теперь заполним все пропуски в этом столбце числом 0:"
572
      ]
573
    },
574
    {
575
      "cell_type": "code",
576
      "execution_count": null,
577
      "metadata": {
578
        "id": "lPJUXA6-I-IB"
579
      },
580
      "outputs": [],
581
      "source": [
582
        "merged_df[\"quantity\"].fillna(0, inplace=True)\n",
583
        "\n",
584
        "merged_df"
585
      ]
586
    },
587
    {
588
      "cell_type": "markdown",
589
      "metadata": {
590
        "id": "y9n61GsAI-ID"
591
      },
592
      "source": [
593
        "Наконец, приведём значения в этом столбце к типу `int`. (Это сделать невозможно, если в столбце содержатся пропуски.)"
594
      ]
595
    },
596
    {
597
      "cell_type": "code",
598
      "execution_count": null,
599
      "metadata": {
600
        "id": "oiC1eYVvI-IE"
601
      },
602
      "outputs": [],
603
      "source": [
604
        "merged_df[\"quantity\"] = merged_df[\"quantity\"].astype(int)\n",
605
        "\n",
606
        "merged_df"
607
      ]
608
    },
609
    {
610
      "cell_type": "markdown",
611
      "metadata": {
612
        "id": "S4WgroS-I-IG"
613
      },
614
      "source": [
615
        "В `DataFrame` можно использовать индексы по умолчанию, а можно и назначить свои. Например, в качестве индексов можно использовать какой-нибудь из столбцов:"
616
      ]
617
    },
618
    {
619
      "cell_type": "code",
620
      "execution_count": null,
621
      "metadata": {
622
        "id": "VfSnwKwsI-IG"
623
      },
624
      "outputs": [],
625
      "source": [
626
        "merged_df.set_index(\"author_id\", inplace=True)\n",
627
        "\n",
628
        "merged_df"
629
      ]
630
    },
631
    {
632
      "cell_type": "markdown",
633
      "metadata": {
634
        "id": "a3YQjgpMI-II"
635
      },
636
      "source": [
637
        "Если что, индексы всегда можно сбросить. Тогда текущие индексы становятся столбцом:"
638
      ]
639
    },
640
    {
641
      "cell_type": "code",
642
      "execution_count": null,
643
      "metadata": {
644
        "id": "5aABCnNqI-IJ"
645
      },
646
      "outputs": [],
647
      "source": [
648
        "merged_df.reset_index(inplace=True)\n",
649
        "\n",
650
        "merged_df"
651
      ]
652
    },
653
    {
654
      "cell_type": "markdown",
655
      "metadata": {
656
        "id": "jMLzx0I7I-IN"
657
      },
658
      "source": [
659
        "### Удаление данных\n",
660
        "\n",
661
        "Для удаления данных из `DataFrame` используется метод `.drop`. В этот метод подаётся метка элемента, который необходимо удалить (индекс строки или название столбца), а также ось `axis`. При `axis=0` удаляется строка, при значении `axis=1` - столбец:"
662
      ]
663
    },
664
    {
665
      "cell_type": "code",
666
      "execution_count": null,
667
      "metadata": {
668
        "id": "akegn7sVI-IO"
669
      },
670
      "outputs": [],
671
      "source": [
672
        "merged_df[\"price\"] = 500\n",
673
        "\n",
674
        "merged_df"
675
      ]
676
    },
677
    {
678
      "cell_type": "code",
679
      "execution_count": null,
680
      "metadata": {
681
        "id": "Iycv-BFlI-IT"
682
      },
683
      "outputs": [],
684
      "source": [
685
        "merged_df.drop(\"price\", axis=1, inplace=True)\n",
686
        "\n",
687
        "merged_df"
688
      ]
689
    },
690
    {
691
      "cell_type": "markdown",
692
      "metadata": {
693
        "id": "6iF3MhWUI-IW"
694
      },
695
      "source": [
696
        "Теперь удалим строку с индексом 1:"
697
      ]
698
    },
699
    {
700
      "cell_type": "code",
701
      "execution_count": null,
702
      "metadata": {
703
        "id": "XbMgSWZ_I-IX"
704
      },
705
      "outputs": [],
706
      "source": [
707
        "merged_df.drop(1, axis=0, inplace=True)\n",
708
        "\n",
709
        "merged_df"
710
      ]
711
    },
712
    {
713
      "cell_type": "markdown",
714
      "metadata": {
715
        "id": "cHSeORq8I-IY"
716
      },
717
      "source": [
718
        "### Сортировка данных\n",
719
        "\n",
720
        "Вернём только что удалённую строку. Напомним, что для этого используется метод `.append`. Кстати, добавлять строки к `DataFrame` можно прямо в виде словарей `dict`:"
721
      ]
722
    },
723
    {
724
      "cell_type": "code",
725
      "execution_count": null,
726
      "metadata": {
727
        "id": "1GbbSJHeI-Ia"
728
      },
729
      "outputs": [],
730
      "source": [
731
        "merged_df = merged_df.append(\n",
732
        "    {\n",
733
        "        \"author_id\": 2,\n",
734
        "        \"author_name\": \"Толстой\",\n",
735
        "        \"book_title\": \"Война и мир\",\n",
736
        "        \"quantity\": 1,\n",
737
        "    },\n",
738
        "    ignore_index=True,\n",
739
        ")\n",
740
        "\n",
741
        "merged_df"
742
      ]
743
    },
744
    {
745
      "cell_type": "markdown",
746
      "metadata": {
747
        "id": "jnJVEYYJI-Ih"
748
      },
749
      "source": [
750
        "Параметр `ignore_index=True` подаётся сюда, чтобы индексы соединяемых таблиц не учитывались. В результирующей таблице будут использованы стандартные последовательные индексы, начинающиеся с 0.\n",
751
        "\n",
752
        "Отсортируем эту таблицу по столбцу `author_id`. Это делается с помощью метода `.sort_values`:"
753
      ]
754
    },
755
    {
756
      "cell_type": "code",
757
      "execution_count": null,
758
      "metadata": {
759
        "id": "WlwQC7ZgI-Ih"
760
      },
761
      "outputs": [],
762
      "source": [
763
        "merged_df.sort_values(by=\"author_id\", inplace=True)\n",
764
        "\n",
765
        "merged_df"
766
      ]
767
    },
768
    {
769
      "cell_type": "markdown",
770
      "metadata": {
771
        "id": "gKydz8lII-Ij"
772
      },
773
      "source": [
774
        "Чтобы сбросить индексы, воспользуемся уже известным методом `.reset_index`. В нашем случае, стоит подать в него аргумент `drop=True`, который означает, что текущий столбец из индексов не нужно сохранять в таблице, а можно удалить."
775
      ]
776
    },
777
    {
778
      "cell_type": "code",
779
      "execution_count": null,
780
      "metadata": {
781
        "id": "FvYreG9bI-Ij"
782
      },
783
      "outputs": [],
784
      "source": [
785
        "merged_df.reset_index(drop=True, inplace=True)\n",
786
        "\n",
787
        "merged_df"
788
      ]
789
    },
790
    {
791
      "cell_type": "markdown",
792
      "metadata": {
793
        "id": "dfIIi0LGI-Im"
794
      },
795
      "source": [
796
        "### Соединение таблиц\n",
797
        "\n",
798
        "Для соединения таблиц можно пользоваться функцией `pd.concat`. С этой функцией мы уже знакомились, когда изучали библиотеку `numpy`. Здесь эта функция работает аналогичным образом: соединяет таблицы либо вертикально (если указан параметр `axis=0`), либо горизонтально (если `axis=1`).\n",
799
        "\n",
800
        "Соединение происходит с сохранением индексов, если не указан параметр `ignore_index=True`."
801
      ]
802
    },
803
    {
804
      "cell_type": "code",
805
      "execution_count": null,
806
      "metadata": {
807
        "id": "Jc68kpVPI-Im"
808
      },
809
      "outputs": [],
810
      "source": [
811
        "df1 = pd.DataFrame({\n",
812
        "    'author_id': [3, 5],\n",
813
        "    'author_name': ['Достоевский', 'Чехов'],\n",
814
        "    'book_title': ['Бесы', 'Три сестры'],\n",
815
        "    'quantity': [2, 3],\n",
816
        "})\n",
817
        "\n",
818
        "df2 = pd.concat([merged_df, df1], axis=0, ignore_index=True)\n",
819
        "\n",
820
        "df2"
821
      ]
822
    },
823
    {
824
      "cell_type": "code",
825
      "execution_count": null,
826
      "metadata": {
827
        "id": "G06O6mgeI-Iq"
828
      },
829
      "outputs": [],
830
      "source": [
831
        "df3 = pd.DataFrame(\n",
832
        "    {'price': [700, 450, 500, 400, 350]},\n",
833
        "    index=[1, 2, 3, 5, 6],\n",
834
        ")\n",
835
        "\n",
836
        "df4 = pd.concat([df2, df3], axis=1)\n",
837
        "\n",
838
        "df4"
839
      ]
840
    },
841
    {
842
      "cell_type": "markdown",
843
      "metadata": {
844
        "id": "g7uNIdjiI-Ir"
845
      },
846
      "source": [
847
        "### Операции над таблицами\n",
848
        "\n",
849
        "Как и ранее с массивами `numpy` и `Series`, с таблицами `DataFrame` можно производить различные математические операции. Например, значения различных столбцов можно поэлементно перемножать, складывать и пр."
850
      ]
851
    },
852
    {
853
      "cell_type": "code",
854
      "execution_count": null,
855
      "metadata": {
856
        "id": "5e-ebivAI-Ir"
857
      },
858
      "outputs": [],
859
      "source": [
860
        "df4[\"total\"] = df4[\"quantity\"] * df4[\"price\"]\n",
861
        "\n",
862
        "df4"
863
      ]
864
    },
865
    {
866
      "cell_type": "markdown",
867
      "metadata": {
868
        "id": "NTI-BTHbI-It"
869
      },
870
      "source": [
871
        "С помощью метода `.nlargest` можно вывести несколько наибольших значений. Указывается то, сколько значений нужно вернуть, а также то, по какому именно значению нужно сортировать:"
872
      ]
873
    },
874
    {
875
      "cell_type": "code",
876
      "execution_count": null,
877
      "metadata": {
878
        "id": "qzIHHkGQI-It"
879
      },
880
      "outputs": [],
881
      "source": [
882
        "df4.nlargest(3, \"price\")"
883
      ]
884
    },
885
    {
886
      "cell_type": "markdown",
887
      "metadata": {
888
        "id": "iTygSn5hI-Iv"
889
      },
890
      "source": [
891
        "Имеется также аналогичный метод `.nsmallest`."
892
      ]
893
    },
894
    {
895
      "cell_type": "markdown",
896
      "metadata": {
897
        "id": "rbPPZVFVI-I2"
898
      },
899
      "source": [
900
        "### Группировка данных\n",
901
        "\n",
902
        "Данные в таблице `DataFrame` можно группировать по повторяющимся значениям выбранного столбца. Группировка позволяет вычислять какие-то _агренированные_ значения, т.е. значения, полученные каким-то образом из групп других значений. Например, если мы захотим сгруппировать нашу таблицу по значениям `author_name`, то каждая группа будет содержать все строки с одинаковым значением `author_name`. По таким группам можно затем посчитать какую-нибудь агрегирующую функцию, например, сумму, среднее, минимум и др.\n",
903
        "\n",
904
        "Вот несколько способов это сделать. В первом случае мы просто выбираем конкретный столбец из группировки и применяем к нему какую-то агрегирующую функцию:"
905
      ]
906
    },
907
    {
908
      "cell_type": "code",
909
      "execution_count": 45,
910
      "metadata": {
911
        "id": "2VTGNpTMI-I2"
912
      },
913
      "outputs": [],
914
      "source": [
915
        "groupby = df4.groupby(\"author_name\")"
916
      ]
917
    },
918
    {
919
      "cell_type": "code",
920
      "execution_count": null,
921
      "metadata": {
922
        "id": "T1UW_htmI-I3"
923
      },
924
      "outputs": [],
925
      "source": [
926
        "groupby[\"price\"].mean()"
927
      ]
928
    },
929
    {
930
      "cell_type": "markdown",
931
      "metadata": {
932
        "id": "hkYvCWkBI-I5"
933
      },
934
      "source": [
935
        "Второй способ - с помощью метода `.agg`. Данный метод является более гибким. Например, он позволяет вычислять одновременно несколько различных агрегирующих функций от разных столбцов:"
936
      ]
937
    },
938
    {
939
      "cell_type": "code",
940
      "execution_count": null,
941
      "metadata": {
942
        "id": "gTWXVizZI-I5"
943
      },
944
      "outputs": [],
945
      "source": [
946
        "groupby.agg({\"price\": \"max\", \"total\": \"count\"})"
947
      ]
948
    }
949
  ],
950
  "metadata": {
951
    "colab": {
952
      "provenance": []
953
    },
954
    "kernelspec": {
955
      "display_name": "Python 3",
956
      "language": "python",
957
      "name": "python3"
958
    },
959
    "language_info": {
960
      "codemirror_mode": {
961
        "name": "ipython",
962
        "version": 3
963
      },
964
      "file_extension": ".py",
965
      "mimetype": "text/x-python",
966
      "name": "python",
967
      "nbconvert_exporter": "python",
968
      "pygments_lexer": "ipython3",
969
      "version": "3.7.4"
970
    }
971
  },
972
  "nbformat": 4,
973
  "nbformat_minor": 0
974
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.