pandas
Индексирование и выбор данных
Поиск…
Выбрать столбец по метке
# Create a sample DF
df = pd.DataFrame(np.random.randn(5, 3), columns=list('ABC'))
# Show DF
df
A B C
0 -0.467542 0.469146 -0.861848
1 -0.823205 -0.167087 -0.759942
2 -1.508202 1.361894 -0.166701
3 0.394143 -0.287349 -0.978102
4 -0.160431 1.054736 -0.785250
# Select column using a single label, 'A'
df['A']
0 -0.467542
1 -0.823205
2 -1.508202
3 0.394143
4 -0.160431
# Select multiple columns using an array of labels, ['A', 'C']
df[['A', 'C']]
A C
0 -0.467542 -0.861848
1 -0.823205 -0.759942
2 -1.508202 -0.166701
3 0.394143 -0.978102
4 -0.160431 -0.785250
Дополнительная информация: http://pandas.pydata.org/pandas-docs/version/0.18.0/indexing.html#selection-by-label
Выбрать по местоположению
Метод iloc
(short for integer location ) позволяет выбирать строки фрейма данных на основе их индекса местоположения. Таким образом можно срезать тактовые кадры так же, как с помощью списка разрезов на языке Python.
df = pd.DataFrame([[11, 22], [33, 44], [55, 66]], index=list("abc"))
df
# Out:
# 0 1
# a 11 22
# b 33 44
# c 55 66
df.iloc[0] # the 0th index (row)
# Out:
# 0 11
# 1 22
# Name: a, dtype: int64
df.iloc[1] # the 1st index (row)
# Out:
# 0 33
# 1 44
# Name: b, dtype: int64
df.iloc[:2] # the first 2 rows
# 0 1
# a 11 22
# b 33 44
df[::-1] # reverse order of rows
# 0 1
# c 55 66
# b 33 44
# a 11 22
Расположение строк может быть объединено с расположением столбца
df.iloc[:, 1] # the 1st column
# Out[15]:
# a 22
# b 44
# c 66
# Name: 1, dtype: int64
См. Также: Выбор по позиции
Нарезка этикетками
При использовании меток в результаты включены как начало, так и стоп.
import pandas as pd
import numpy as np
np.random.seed(5)
df = pd.DataFrame(np.random.randint(100, size=(5, 5)), columns = list("ABCDE"),
index = ["R" + str(i) for i in range(5)])
# Out:
# A B C D E
# R0 99 78 61 16 73
# R1 8 62 27 30 80
# R2 7 76 15 53 80
# R3 27 44 77 75 65
# R4 47 30 84 86 18
Строки от R0
до R2
:
df.loc['R0':'R2']
# Out:
# A B C D E
# R0 9 41 62 1 82
# R1 16 78 5 58 0
# R2 80 4 36 51 27
Обратите внимание, что loc
отличается от iloc
потому что iloc
исключает конечный индекс
df.loc['R0':'R2'] # rows labelled R0, R1, R2
# Out:
# A B C D E
# R0 9 41 62 1 82
# R1 16 78 5 58 0
# R2 80 4 36 51 27
# df.iloc[0:2] # rows indexed by 0, 1
# A B C D E
# R0 99 78 61 16 73
# R1 8 62 27 30 80
Столбцы от C
до E
:
df.loc[:, 'C':'E']
# Out:
# C D E
# R0 62 1 82
# R1 5 58 0
# R2 36 51 27
# R3 68 38 83
# R4 7 30 62
Выбор смешанной позиции и метки
DataFrame:
import pandas as pd
import numpy as np
np.random.seed(5)
df = pd.DataFrame(np.random.randint(100, size=(5, 5)), columns = list("ABCDE"),
index = ["R" + str(i) for i in range(5)])
df
Out[12]:
A B C D E
R0 99 78 61 16 73
R1 8 62 27 30 80
R2 7 76 15 53 80
R3 27 44 77 75 65
R4 47 30 84 86 18
Выберите строки по положению и столбцы по метке:
df.ix[1:3, 'C':'E']
Out[19]:
C D E
R1 5 58 0
R2 36 51 27
Если индекс является целым числом, .ix
будет использовать метки, а не позиции:
df.index = np.arange(5, 10)
df
Out[22]:
A B C D E
5 9 41 62 1 82
6 16 78 5 58 0
7 80 4 36 51 27
8 31 2 68 38 83
9 19 18 7 30 62
#same call returns an empty DataFrame because now the index is integer
df.ix[1:3, 'C':'E']
Out[24]:
Empty DataFrame
Columns: [C, D, E]
Index: []
Булевское индексирование
Можно выбрать строки и столбцы блока данных с помощью булевых массивов.
import pandas as pd
import numpy as np
np.random.seed(5)
df = pd.DataFrame(np.random.randint(100, size=(5, 5)), columns = list("ABCDE"),
index = ["R" + str(i) for i in range(5)])
print (df)
# A B C D E
# R0 99 78 61 16 73
# R1 8 62 27 30 80
# R2 7 76 15 53 80
# R3 27 44 77 75 65
# R4 47 30 84 86 18
mask = df['A'] > 10
print (mask)
# R0 True
# R1 False
# R2 False
# R3 True
# R4 True
# Name: A, dtype: bool
print (df[mask])
# A B C D E
# R0 99 78 61 16 73
# R3 27 44 77 75 65
# R4 47 30 84 86 18
print (df.ix[mask, 'C'])
# R0 61
# R3 77
# R4 84
# Name: C, dtype: int32
print(df.ix[mask, ['C', 'D']])
# C D
# R0 61 16
# R3 77 75
# R4 84 86
Больше в документации pandas .
Фильтрация столбцов (выбор «интересный», удаление ненужных, использование RegEx и т. Д.)
сгенерировать образец DF
In [39]: df = pd.DataFrame(np.random.randint(0, 10, size=(5, 6)), columns=['a10','a20','a25','b','c','d'])
In [40]: df
Out[40]:
a10 a20 a25 b c d
0 2 3 7 5 4 7
1 3 1 5 7 2 6
2 7 4 9 0 8 7
3 5 8 8 9 6 8
4 8 1 0 4 4 9
показать столбцы, содержащие букву 'a'
In [41]: df.filter(like='a')
Out[41]:
a10 a20 a25
0 2 3 7
1 3 1 5
2 7 4 9
3 5 8 8
4 8 1 0
показать столбцы с использованием фильтра RegEx (b|c|d)
- b
или c
или d
:
In [42]: df.filter(regex='(b|c|d)')
Out[42]:
b c d
0 5 4 7
1 7 2 6
2 0 8 7
3 9 6 8
4 4 4 9
показать все столбцы , кроме тех , начиная с (другими словами удалять / удалить все столбцы , удовлетворяющие заданной RegEx) a
In [43]: df.ix[:, ~df.columns.str.contains('^a')]
Out[43]:
b c d
0 5 4 7
1 7 2 6
2 0 8 7
3 9 6 8
4 4 4 9
Фильтрация / выбор строк с использованием метода `.query ()`
import pandas as pd
генерировать случайные DF
df = pd.DataFrame(np.random.randint(0,10,size=(10, 3)), columns=list('ABC'))
In [16]: print(df)
A B C
0 4 1 4
1 0 2 0
2 7 8 8
3 2 1 9
4 7 3 8
5 4 0 7
6 1 5 5
7 6 7 8
8 6 7 3
9 6 4 5
выберите строки, где значения в столбце A > 2
и значения в столбце B < 5
In [18]: df.query('A > 2 and B < 5')
Out[18]:
A B C
0 4 1 4
4 7 3 8
5 4 0 7
9 6 4 5
с использованием .query()
с переменными для фильтрации
In [23]: B_filter = [1,7]
In [24]: df.query('B == @B_filter')
Out[24]:
A B C
0 4 1 4
3 2 1 9
7 6 7 8
8 6 7 3
In [25]: df.query('@B_filter in B')
Out[25]:
A B C
0 4 1 4
Наклонная нарезка
Может возникнуть необходимость пересекать элементы серии или строки кадра данных таким образом, что следующий элемент или следующая строка зависит от ранее выбранного элемента или строки. Это называется зависимостью пути.
Рассмотрим следующие временные ряды s
с нерегулярной частотой.
#starting python community conventions
import numpy as np
import pandas as pd
# n is number of observations
n = 5000
day = pd.to_datetime(['2013-02-06'])
# irregular seconds spanning 28800 seconds (8 hours)
seconds = np.random.rand(n) * 28800 * pd.Timedelta(1, 's')
# start at 8 am
start = pd.offsets.Hour(8)
# irregular timeseries
tidx = day + start + seconds
tidx = tidx.sort_values()
s = pd.Series(np.random.randn(n), tidx, name='A').cumsum()
s.plot();
Предположим, что условие зависит от пути. Начиная с первого члена серии, я хочу захватить каждый последующий элемент таким образом, чтобы абсолютная разница между этим элементом и текущим элементом была больше или равна x
.
Мы решим эту проблему, используя генераторы python.
Функция генератора
def mover(s, move_size=10):
"""Given a reference, find next value with
an absolute difference >= move_size"""
ref = None
for i, v in s.iteritems():
if ref is None or (abs(ref - v) >= move_size):
yield i, v
ref = v
Тогда мы можем определить, что новая серия moves
так
moves = pd.Series({i:v for i, v in mover(s, move_size=10)},
name='_{}_'.format(s.name))
Построение их обоих
moves.plot(legend=True)
s.plot(legend=True)
Аналогом для data-кадров будет:
def mover_df(df, col, move_size=2):
ref = None
for i, row in df.iterrows():
if ref is None or (abs(ref - row.loc[col]) >= move_size):
yield row
ref = row.loc[col]
df = s.to_frame()
moves_df = pd.concat(mover_df(df, 'A', 10), axis=1).T
moves_df.A.plot(label='_A_', legend=True)
df.A.plot(legend=True)
Получить первые / последние n строк кадра данных
Чтобы просмотреть первые или последние несколько записей фрейма данных, вы можете использовать методы head
и tail
Чтобы вернуть первые n строк, используйте DataFrame.head([n])
df.head(n)
Чтобы вернуть последние n строк, используйте DataFrame.tail([n])
df.tail(n)
Без аргумента n эти функции возвращают 5 строк.
Обратите внимание, что обозначение среза для head
/ tail
будет:
df[:10] # same as df.head(10)
df[-10:] # same as df.tail(10)
Выбор отдельных строк в кадре данных
Позволять
df = pd.DataFrame({'col_1':['A','B','A','B','C'], 'col_2':[3,4,3,5,6]})
df
# Output:
# col_1 col_2
# 0 A 3
# 1 B 4
# 2 A 3
# 3 B 5
# 4 C 6
Чтобы получить отдельные значения в col_1
вы можете использовать Series.unique()
df['col_1'].unique()
# Output:
# array(['A', 'B', 'C'], dtype=object)
Но Series.unique () работает только для одного столбца.
Для имитации выбора уникального col_1, col_2 SQL вы можете использовать DataFrame.drop_duplicates()
:
df.drop_duplicates()
# col_1 col_2
# 0 A 3
# 1 B 4
# 3 B 5
# 4 C 6
Это даст вам все уникальные строки в области данных. Так что если
df = pd.DataFrame({'col_1':['A','B','A','B','C'], 'col_2':[3,4,3,5,6], 'col_3':[0,0.1,0.2,0.3,0.4]})
df
# Output:
# col_1 col_2 col_3
# 0 A 3 0.0
# 1 B 4 0.1
# 2 A 3 0.2
# 3 B 5 0.3
# 4 C 6 0.4
df.drop_duplicates()
# col_1 col_2 col_3
# 0 A 3 0.0
# 1 B 4 0.1
# 2 A 3 0.2
# 3 B 5 0.3
# 4 C 6 0.4
Чтобы указать столбцы, которые следует учитывать при выборе уникальных записей, передайте их в качестве аргументов
df = pd.DataFrame({'col_1':['A','B','A','B','C'], 'col_2':[3,4,3,5,6], 'col_3':[0,0.1,0.2,0.3,0.4]})
df.drop_duplicates(['col_1','col_2'])
# Output:
# col_1 col_2 col_3
# 0 A 3 0.0
# 1 B 4 0.1
# 3 B 5 0.3
# 4 C 6 0.4
# skip last column
# df.drop_duplicates(['col_1','col_2'])[['col_1','col_2']]
# col_1 col_2
# 0 A 3
# 1 B 4
# 3 B 5
# 4 C 6
Источник: как «выбрать отдельный» для нескольких столбцов фрейма данных в пандах? ,
Отфильтруйте строки с отсутствующими данными (NaN, None, NaT)
Если у вас есть dataframe с отсутствующими данными ( NaN
, pd.NaT
, None
), вы можете отфильтровать неполные строки
df = pd.DataFrame([[0,1,2,3],
[None,5,None,pd.NaT],
[8,None,10,None],
[11,12,13,pd.NaT]],columns=list('ABCD'))
df
# Output:
# A B C D
# 0 0 1 2 3
# 1 NaN 5 NaN NaT
# 2 8 NaN 10 None
# 3 11 12 13 NaT
DataFrame.dropna
все строки, содержащие хотя бы одно поле с отсутствующими данными
df.dropna()
# Output:
# A B C D
# 0 0 1 2 3
Чтобы просто удалить строки, в которых отсутствуют данные в указанных столбцах, используйте subset
df.dropna(subset=['C'])
# Output:
# A B C D
# 0 0 1 2 3
# 2 8 NaN 10 None
# 3 11 12 13 NaT
Используйте параметр inplace = True
для замены на месте фильтрованным фреймом.