Глава 5. Введение в pandas
Pandas — это библиотека, которая делает работу с данными проще и быстрее. Она часто используется вместе с другими инструментами, такими как NumPy и SciPy для численных вычислений, statsmodels и scikit-learn для анализа данных и matplotlib для визуализации данных. Pandas основана на массивах NumPy, особенно на их функциях и методах работы с данными без использования циклов for.
Хотя pandas использует многие стили кодирования NumPy, основное отличие заключается в том, что pandas специально разработана для обработки табличных и смешанных данных, в то время как NumPy больше подходит для работы с однородными массивами числовых данных.
С момента своего открытия в 2010 году pandas стала большой библиотекой, применяемой во многих реальных проектах. Сообщество разработчиков насчитывает более 800 независимых участников, которые вносят свой вклад в проект, решая повседневные задачи по обработке данных.
В этой книге я буду использовать следующий способ импорта pandas:
In [1]: import pandas as pd
Таким образом, всякий раз, когда вы видите pd. в коде, вы должны думать о pandas. Поскольку Series и DataFrame используются очень часто, их импорт в локальное пространство имён будет более удобным:
In [2]: from pandas import Series, DataFrame
5.1. Введение в структуры данных pandas
Для работы с pandas вам необходимо ознакомиться с двумя основными структурами данных: Series и DataFrame. Хотя они не могут решить все проблемы, они предоставляют надёжную и простую основу для большинства приложений.
Series
Series — это объект, похожий на одномерный массив, состоящий из набора данных (различных типов данных NumPy) и связанного с ними набора меток данных (индексов). Самый простой Series можно создать, используя только набор данных:
In [11]: obj = pd.Series([4, 7, -5, 3])
In [12]: obj
Out[12]:
0 4
1 7
2 -5
3 3
dtype: int64
Строковое представление Series выглядит следующим образом: индексы слева, значения справа. Так как мы не указали индексы для данных, pandas автоматически создала целочисленный индекс от 0 до N-1 (где N — длина данных). Вы можете получить представление массива и объекта индекса для Series с помощью атрибутов values и index:
In [13]: obj.values
Out[13]: array([ 4, 7, -5, 3])
In [14]: obj.index # like range(4)
Out[14]: RangeIndex(start=0, stop=4, step=1)
Обычно мы хотим, чтобы созданный Series имел индекс, который может идентифицировать отдельные точки данных:
In [15]: obj2 = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
In [16]: obj2
Out[16]:
d 4
b 7
a -5
c 3
dtype: int64
In [17]: obj2.index
Out[17]: Index(['d', 'b', 'a', 'c'], dtype='object')
По сравнению с обычными массивами NumPy вы можете выбирать отдельные или группы значений из Series по индексу:
In [18]: obj2['a']
Out[18]: -5
In [19]: obj2['d'] = 6
In [20]: obj2[['c', 'a', 'd']]
Out[20]:
c 3
a -5
d 6
dtype: int64
['c', 'a', 'd'] — это список индексов, даже если он содержит строки, а не целые числа.
Использование функций NumPy или аналогичных операций (например, фильтрация по булевому массиву, умножение на скаляр, применение математических функций) сохраняет связь между значениями и индексами:
In [21]: obj2[obj2 > 0]
Out[21]:
d 6
b 7
c 3
dtype: int64
In [22]: obj2 * 2
Out[22]:
d 12
b 14
a -10
c 6
dtype: int64
In [23]: np.exp(obj2)
Out[23]:
d 403.428793
b 1096.633158
a 0.006738
c 20.085537
dtype: float64
Также можно рассматривать Series как упорядоченный словарь с фиксированным размером, поскольку он представляет собой отображение между индексами и значениями. Его можно использовать во многих функциях, требующих параметров словаря:
In [24]: 'b' in obj2
Out[24]: True
In [25]: 'e' in obj2
Out[25]: False
Если данные хранятся в словаре Python, вы также можете создать Series напрямую из него:
In [26]: sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
In [27]: obj3 = pd.Series(sdata)
In [28]: obj3
Out[28]:
Ohio 35000
Oregon 16000
Texas 71000
Utah 5000
dtype: int64
При передаче одного словаря результат Series будет иметь индексы, соответствующие ключам исходного словаря (в отсортированном порядке). Вы можете передать отсортированный список ключей, чтобы изменить порядок:
In [29]: states = ['California', 'Ohio', 'Oregon', 'Texas']
In [30]: obj4 = pd.Series(sdata, index=states)
In [31]: obj4
Out[31]:
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64
В этом примере значения, соответствующие трём ключам в states, будут найдены и помещены в соответствующие позиции, но поскольку значение для «California» не найдено, оно будет NaN (не число), которое используется в pandas для обозначения отсутствующих или NA значений. Поскольку «Utah» отсутствует в states, он исключается из результата.
Я буду использовать термины «отсутствующий» или «NA» для обозначения пропущенных данных. Функции pandas isnull и notnull можно использовать для проверки наличия пропущенных данных:
In [32]: pd.isnull(obj4)
Out[32]:
California True
Ohio False
Oregon False
Texas False
dtype: bool
In [33]: pd.notnull(obj4)
Out[33]:
California False
Ohio True
Oregon True
Texas True
dtype: bool
Серия также имеет аналогичные методы экземпляра:
In [34]: obj4.isnull()
Out[34]:
California True
Ohio False
Oregon False
Texas False
dtype: bool
Я подробно расскажу об обработке пропущенных данных в главе 7.
Для многих приложений наиболее важной функцией Series является автоматическое выравнивание данных по операциям в соответствии с метками индексов:
In [35]: obj3
Out[35]:
Ohio 35000
Oregon 16000
Texas 71000
Utah 5000
dtype: int64
In [36]: obj4
Out[36]:
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64
In [37]: obj3 + obj4
Out[37]:
California NaN
Ohio 70000.0
Oregon 32000.0
Texas 142000.0
Utah NaN
dtype: float64
Функция выравнивания данных будет подробно рассмотрена позже. Если вы работали с базами данных, вы можете рассматривать её как операцию, подобную join.
У объектов Series есть атрибут name, который тесно связан с ключевыми функциями pandas:
In [38]: obj4.name = 'population'
In [39]: obj4.index.name = 'state'
In [40]: obj4
Out[40]:
state
California NaN
Ohio 35000.0
Oregon 16000.0 ```
Series的索引可以通过赋值的方式就地修改:
```python
In [41]: obj
Out[41]:
0 4
1 7
2 -5
3 3
dtype: int64
In [42]: obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']
In [43]: obj
Out[43]:
Bob 4
Steve 7
Jeff -5
Ryan 3
dtype: int64
DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引,它可以被看做由Series组成的字典(共用同一个索引)。DataFrame中的数据是以一个或多个二维块存放的(而不是列表、字典或别的一维数据结构)。
建DataFrame的办法有很多,最常用的一种是直接传入一个由等长列表或NumPy数组组成的字典:
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'],
'year': [2000, 2001, 2002, 2001, 2002, 2003],
'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}
frame = pd.DataFrame(data)
结果DataFrame会自动加上索引(跟Series一样),且全部列会被有序排列:
In [45]: frame
Out[45]:
pop state year
0 1.5 Ohio 2000
1 1.7 Ohio 2001
2 3.6 Ohio 2002
3 2.4 Nevada 2001
4 2.9 Nevada 2002
5 3.2 Nevada 2003
如果你使用的是Jupyter notebook,pandas DataFrame对象会以对浏览器友好的HTML表格的方式呈现。
对于特别大的DataFrame,head方法会选取前五行:
In [46]: frame.head()
Out[46]:
pop state year
0 1.5 Ohio 2000
1 1.7 Ohio 2001
2 3.6 Ohio 2002
3 2.4 Nevada 2001
4 2.9 Nevada 2002
Если指定了列序列,则DataFrame的列就会按照指定顺序进行排列:
In [47]: pd.DataFrame(data, columns=['year', 'state', 'pop'])
Out[47]:
year state pop
0 2000 Ohio 1.5
1 2001 Ohio 1.7
2 2002 Ohio 3.6
3 2001 Nevada 2.4
4 2002 Nevada 2.9
5 2003 Nevada 3.2
如果传入的列在数据中找不到,就会在结果中产生缺失值:
In [48]: frame2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
....: index=['one', 'two', 'three', 'four',
....: 'five', 'six'])
In [49]: frame2
Out[49]:
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Ohio 1.7 NaN
three 2002 Ohio 3.6 NaN
four 2001 Nevada 2.4 NaN
five 2002 Nevada 2.9 NaN
six 2003 Nevada 3.2 NaN
In [50]: frame2.columns
Out[50]: Index(['year', 'state', 'pop', 'debt'], dtype='object')
通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series:
In [51]: frame2['state']
Out[51]:
one Ohio
two Ohio
three Ohio
four Nevada
five Nevada
six Nevada
Name: state, dtype: object
In [52]: frame2.year
Out[52]:
one 2000
two 2001
three 2002
four 2001
five 2002
six 2003
Name: year, dtype: int64
笔记:IPython提供了类似属性的访问(即frame2.year)和tab补全。 frame2[column]适用于任何列的名,但是frame2.column只有在列名是一个合理的Python变量名时才适用。
注意,返回的Series拥有原DataFrame相同的索引,且其name属性也已经被相应地设置好了。
行也可以通过位置或名称的方式进行获取,比如用loc属性(稍后将对此进行详细讲解):
In [53]: frame2.loc['three']
Out[53]:
year 2002
state Ohio
pop 3.6
debt NaN
Name: three, dtype: object
列可以通过赋值的方式进行修改。例如,我们可以给那个空的"debt"列赋上一个标量值或一组值:
In [54]: frame2['debt'] = 16.5
In [55]: frame2
Out[55]:
year state pop debt
one 2000 Ohio 1.5 16.5
two 2001 Ohio 1.7 16.5
three 2002 Ohio 3.6 16.5
four 2001 Nevada 2.4 16.5
five 2002 Nevada 2.9 16.5
six 2003 Nevada 3.2 16.5
In [56]: frame2['debt'] = np.arange(6.)
In [57]: frame2
Out[57]:
year state pop debt
one 2000 Ohio 1.5 0.0
two 2001 Ohio 1.7 1.0
three 2002 Ohio 3.6 2.0
four 2001 Nevada 2.4 3.0
five 2002 Nevada 2.9 4.0
six 2003 Nevada 3.2 5.0
将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度相匹配。如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值:
In [58]: val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
In [59]: frame2['debt'] = val
In [60]: frame2
Out[60]:
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Ohio 1.7 -1.2
three 2002 Ohio 3.6 NaN
four 2001 Nevada 2.4 -1.5
five 2002 Nevada 2.9 -1.7
six 2003 Nevada 3.2 NaN
为不存在的列赋值会创建出一个新列。关键字del用于删除列。
作为del的例子,我先添加一个新的布尔值的列,state是否为'Ohio':
In [61]: frame2['eastern'] = frame2.state
``` ```
s1 = pd.Series([7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'])
s2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1],
index=['a', 'c', 'e', 'f', 'g'])
print(s1 + s2)
Результат:
a 5.2
c 1.1
d 3.4
e 0.0
f 4.0
g 3.1
dtype: float64
``` **Перевод текста запроса на русский язык:**
Автоматическая операция выравнивания данных ввела значения NA в неперекрывающиеся индексы. Пропущенные значения будут распространяться во время арифметических операций.
Для DataFrame операция выравнивания будет происходить одновременно для строк и столбцов:
```python
In [155]: df1 = pd.DataFrame(np.arange(9.).reshape((3, 3)), columns=list('bcd'),
.....: index=['Ohio', 'Texas', 'Colorado'])
In [156]: df2 = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'),
.....: index=['Utah', 'Ohio', 'Texas', 'Oregon'])
In [157]: df1
Out[157]:
b c d
Ohio 0.0 1.0 2.0
Texas 3.0 4.0 5.0
Colorado 6.0 7.0 8.0
In [158]: df2
Out[158]:
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
Их сложение вернёт новый DataFrame, индекс и столбцы которого будут объединением индексов и столбцов двух исходных DataFrame:
In [159]: df1 + df2
Out[159]:
b c d e
Colorado NaN NaN NaN NaN
Ohio 3.0 NaN 6.0 NaN
Oregon NaN NaN NaN NaN
Texas 9.0 NaN 12.0 NaN
Utah NaN NaN NaN NaN
Поскольку столбцы 'c' и 'e' отсутствуют в обоих объектах DataFrame, они представлены пропущенными значениями в результате. То же самое относится к строкам.
Если объекты DataFrame складываются без общих столбцов или меток строк, результат будет пустым:
In [160]: df1 = pd.DataFrame({'A': [1, 2]})
In [161]: df2 = pd.DataFrame({'B': [3, 4]})
In [162]: df1
Out[162]:
A
0 1
1 2
In [163]: df2
Out[163]:
B
0 3
1 4
In [164]: df1 - df2
Out[164]:
A B
0 NaN NaN
1 NaN NaN
При выполнении арифметических операций над объектами с разными индексами вы можете захотеть заполнить специальное значение (например, 0) вместо отсутствующего значения в одном из объектов:
In [165]: df1 = pd.DataFrame(np.arange(12.).reshape((3, 4)),
.....: columns=list('abcd'))
In [166]: df2 = pd.DataFrame(np.arange(20.).reshape((4, 5)),
.....: columns=list('abcde'))
In [167]: df2.loc[1, 'b'] = np.nan
In [168]: df1
Out[168]:
a b c d
0 0.0 1.0 2.0 3.0
1 4.0 5.0 6.0 7.0
2 8.0 9.0 10.0 11.0
In [169]: df2
Out[169]:
a b c d e
0 0.0 1.0 2.0 3.0 4.0
1 5.0 NaN 7.0 8.0 9.0
2 10.0 11.0 12.0 13.0 14.0
3 15.0 16.0 17.0 18.0 19.0
Сложение этих объектов приведёт к появлению пропущенных значений там, где нет перекрытия:
In [170]: df1 + df2
Out[170]:
a b c d e
0 0.0 2.0 4.0 6.0 NaN
1 9.0 NaN 13.0 15.0 NaN
2 18.0 20.0 22.0 24.0 NaN
3 NaN NaN NaN NaN NaN
Используя метод add объекта df1 и передавая df2 и fill_value=0, можно получить следующий результат:
In [171]: df1.add(df2, fill_value=0)
Out[171]:
a b c d e
0 0.0 2.0 4.0 6.0 4.0
1 9.0 5.0 13.0 15.0 9.0
2 18.0 20.0 22.0 24.0 14.0
3 15.0 16.0 17.0 18.0 19.0
В таблице 5-5 перечислены арифметические методы Series и DataFrame. Каждый из них имеет копию, начинающуюся с буквы r, которая меняет порядок параметров. Поэтому эти два утверждения эквивалентны:
In [172]: 1 / df1
Out[172]:
a b c d
0 inf 1.000000 0.500000 0.333333
1 0.250000 0.200000 0.166667 0.142857
2 0.125000 0.111111 0.100000 0.090909
In [173]: df1.rdiv(1)
Out[173]:
a b c d
0 inf 1.000000 0.500000 0.333333
1 0.250000 0.200000 0.166667 0.142857
2 0.125000 0.111111 0.100000 0.090909
Аналогично, при повторном индексировании Series или DataFrame также можно указать значение заполнения:
In [174]: df1.reindex(columns=df2.columns, fill_value=0)
Out[174]:
a b c d e
0 0.0 1.0 2.0 3.0 0
1 4.0 5.0 6.0 7.0 0
2 8.0 9.0 10.0 11.0 0
Как и в случае с двумерными массивами NumPy разных размеров, операции между DataFrame и Series также имеют чёткие правила. Рассмотрим показательный пример вычисления разницы между двумерным массивом и одной из его строк:
In [175]: arr = np.arange(12.).reshape((3, 4))
In [176]: arr
Out[176]:
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])
In [177]: arr[0]
Out[177]: array([ 0., 1., 2., 3.])
In [178]: arr - arr[0]
Out[178]:
array([[ 0., 0., 0., 0.],
[ 4., 4., 4., 4.],
[ 8., 8., 8., 8.]])
Когда мы вычитаем arr[0] из arr, эта операция выполняется для каждой строки. Это называется вещанием (broadcasting), более подробно оно рассматривается в приложении А. Операции между DataFrame и Series примерно такие же:
In [179]: frame = pd.DataFrame(np.arange(12.).reshape((4, 3)),
.....: columns=list('bde'),
.....: index=['Utah', 'Ohio', 'Texas', 'Oregon'])
In [180]: series = frame.iloc[0]
In [181]: frame
Out[181]:
b d e
Utah 0.0 1.0
``` **Перевод текста на русский язык:**
При сортировке, любые пропущенные значения по умолчанию будут помещены в конец Series:
In [209]: obj = pd.Series([4, np.nan, 7, np.nan, -3, 2])
In [210]: obj.sort_values() Out[210]: 2 -3.0 5 2.0 0 4.0 1 NaN 3 NaN 4 7.0 dtype: float64
Когда вы сортируете DataFrame, вы можете захотеть отсортировать по одному или нескольким столбцам значений. Для этого передайте имена столбцов в параметр by метода sort_values:
In [211]: frame = pd.DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
In [212]: frame Out[212]: a b 0 0 4 1 1 7 2 0 -3 3 1 2
In [213]: frame.sort_values(by='b') Out[213]: a b 2 0 -3 3 1 2 0 0 4 1 1 7
Чтобы отсортировать несколько столбцов, передайте список имён столбцов:
In [214]: frame.sort_values(by=['a', 'b']) Out[214]: a b 2 0 -3 0 0 4 3 1 2 1 1 7
Ранги будут начинаться с 1 и продолжаться до количества действительных данных в массиве. Далее рассмотрим методы rank и Series и DataFrame. По умолчанию метод rank разрушает связи между равными значениями путём присвоения среднего ранга:
In [215]: obj = pd.Series([7, -5, 7, 4, 2, 0, 4]) In [216]: obj.rank() Out[216]: 0 6.5 1 1.0 2 6.5 3 4.5 4 3.0 5 2.0 6 4.5 dtype: float64
Вы также можете присвоить ранги в соответствии с порядком появления значений в исходных данных:
In [217]: obj.rank(method='first') Out[217]: 0 6.0 1 1.0 2 7.0 3 4.0 4 3.0 5 2.0 6 5.0 dtype: float64
Здесь элементы 0 и 2 не получили средний ранг 6,5, они были присвоены ранги 6 и 7, потому что элемент 0 идёт перед элементом 2 в исходных данных.
Также можно выполнить ранжирование в обратном порядке:
In [218]: obj.rank(ascending=False, method='max') Out[218]: 0 2.0 1 7.0 2 2.0 3 4.0 4 5.0 5 6.0 6 4.0 dtype: float64
В таблице 5-6 перечислены все методы для разрушения связей между равными значениями. DataFrame может вычислять ранги по строкам или столбцам:
In [219]: frame = pd.DataFrame({'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1], .....: 'c': [-2, 5, 8, -2.5]})
In [220]: frame Out[220]: a b c 0 0 4.3 -2.0 1 1 7.0 5.0 2 0 -3.0 8.0 3 1 2.0 -2.5
In [221]: frame.rank(axis='columns') Out[221]: a b c 0 2.0 3.0 1.0 1 1.0 3.0 2.0 2 2.0 1.0 3.0 3 2.0 3.0 1.0
| Метод | Описание |
| --- | --- |
| first | Ранги присваиваются в порядке появления значений |
| dense | Значениям, имеющим одинаковый ранг, присваивается следующий доступный ранг |
| min | Минимальное значение ранга среди всех равных значений |
| max | Максимальное значение ранга среди всех равных значений |
| average | Средний ранг среди всех равных значений |
**Пример с повторяющимися индексами:**
До сих пор все примеры имели уникальные индексы. Хотя многие функции pandas (например, reindex) требуют уникальных индексов, это не обязательно. Рассмотрим простой пример Series с повторяющимися значениями индекса:
In [222]: obj = pd.Series(range(5), index=['a', 'a', 'b', 'b', 'c'])
In [223]: obj Out[223]: a 0 a 1 b 2 b 3 c 4 dtype: int64
Свойство is_unique индекса сообщает, является ли он уникальным:
In [224]: obj.index.is_unique Out[224]: False
Для индексов с повторяющимися значениями данные выбираются по-разному. Если индекс соответствует нескольким значениям, возвращается Series, а если одному значению, то возвращается скалярное значение:
In [225]: obj['a'] Out[225]: a 0 a 1 dtype: int64
In [226]: obj['c'] Out[226]: 4
Это делает код более сложным, поскольку тип вывода индекса зависит от того, есть ли у него повторяющиеся значения.
То же самое происходит при индексации строк DataFrame:
In [227]: df = pd.DataFrame(np.random.randn(4, 3), index=['a', 'a', 'b', 'b'])
In [228]: df Out[228]: 0 1 2 a 0.274992 0.228913 1.352917 a 0.886429 -2.001637 -0.371843 b 1.669025 -0.438570 -0.539741 b 0.476985 3.248944 -1.021228
In [229]: df.loc['b'] Out[229]: 0 1 2 b 1.669025 -0.438570 -0.539741 b 0.476985 3.248944 -1.021228
# 5.3 Сводные и статистические вычисления
Объекты pandas имеют набор общих математических и статистических методов. Большинство из них относятся к сводным и статистическим вычислениям и используются для извлечения одного значения из Series (например, sum или mean) или одного Series из строки или столбца DataFrame. В отличие от соответствующих методов NumPy, они основаны на предположении отсутствия пропущенных данных. Рассмотрим простой DataFrame:
In [230]: df = pd.DataFrame([[1.4, np.nan], [7.1, -4.5], .....: [np.nan, np.nan], [0.75, -1.3]], .....: index=['a', 'b', 'c', 'd'], .....: columns=['one', 'two'])
In [231]: df Out[231]: one two a 1.40 NaN b 7.10 -4.5 c NaN NaN d 0.75 -1.3
Вызов метода sum DataFrame возвращает Series с суммой столбцов:
In [232]: df.sum() Out[232]: one 9.25 two -5.80 dtype: float64
Передача axis='columns' или axis=1 приведёт к суммированию по строкам:
In [233]: df.sum(axis=1) Out[233]: a 1.40 b 2.60 c NaN d -0.55
NA значения автоматически исключаются, если только весь срез (здесь строка или столбец) не состоит из NA. Опция skipna позволяет отключить эту функцию:
In [234]: df.mean(axis='columns', skipna=False) Out[234]: a NaN b 1.300 c NaN d -0.275 dtype: float64
Таблица 5-7 содержит список наиболее часто используемых опций этих методов.
| Метод | Описание |
| --- | --- |
| axis | Ось, по которой выполняется операция (по умолчанию 0) |
| skipna | Исключать ли пропущенные значения (по умолчанию True) |
Некоторые методы (такие как idxmin и idxmax) возвращают косвенные статистики (например, индекс минимального или максимального значения):
In [235]: df.idxmax() Out[235]: one b two d dtype: object
Другие методы являются кумулятивными:
In
In [257]: маска = obj.isin(['b', 'c'])
In [258]: маска
Out[258]:
0 True
1 False
2 False
3 False
4 False
5 True
6 True
7 True
8 True
dtype: bool
In [259]: obj[маска]
Out[259]:
0 с
5 b
6 b
7 c
8 c
dtype: объект
С isin похож метод Index.get_indexer, который может дать вам массив индексов от массива, возможно содержащего повторяющиеся значения, до другого массива с различными значениями:
In [260]: to_match = pd.Series(['c', 'a', 'b', 'b', 'c', 'a'])
In [261]: unique_vals = pd.Series(['c', 'b', 'a'])
In [262]: pd.Index(unique_vals).get_indexer(to_match)
Out[262]: array([0, 2, 1, 1, 0, 2])
Таблица 5-9 содержит некоторую справочную информацию об этих методах.
Метод | Описание |
---|---|
isin | Проверяет, находится ли значение в списке значений |
get_indexer | Возвращает массив индексов для сопоставления элементов одного массива с элементами другого массива |
Иногда вы можете захотеть получить столбчатую диаграмму для нескольких связанных столбцов в DataFrame. Например:
In [263]: data = pd.DataFrame({'Qu1': [1, 3, 4, 3, 4],
.....: 'Qu2': [2, 3, 1, 2, 3],
.....: 'Qu3': [1, 5, 2, 4, 4]})
In [264]: data
Out[264]:
Qu1 Qu2 Qu3
0 1 2 1
1 3 3 5
2 4 1 2
3 3 2 4
4 4 3 4
Если передать pandas.value_counts в функцию apply этого DataFrame, то получится:
In [265]: result = data.apply(pd.value_counts).fillna(0)
In [266]: result
Out[266]:
Qu1 Qu2 Qu3
1 1.0 1.0 1.0
2 0.0 2.0 1.0
3 2.0 2.0 0.0
4 2.0 0.0 2.0
5 0.0 0.0 1.0
Здесь метки строк в результате представляют собой все уникальные значения столбцов. Последующие значения частоты — это количество соответствующих значений в каждом столбце.
В следующей главе мы обсудим инструменты для чтения (или загрузки) и записи наборов данных с помощью pandas.
Затем мы более подробно рассмотрим инструменты для очистки, упорядочивания, анализа и визуализации данных с использованием pandas.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )