Как перебирать строки в фрейме данных Pandas
Итерация по DataFrames pandas определенно не лучшая практика, и вам следует рассматривать это только тогда, когда это абсолютно необходимо, и когда вы исчерпали все другие возможные варианты, которые, вероятно, будут более элегантными и эффективными.
Итерация по объектам pandas обычно выполняется медленно. Во многих случаях итерация вручную по строкам не требуется, и ее можно избежать.
В сегодняшней статье мы обсудим, как избежать повторения кадров данных в pandas. Мы также рассмотрим “контрольный список”, на который вам, возможно, потребуется ссылаться каждый раз, прежде чем выбрать итеративный подход. Кроме того, мы рассмотрим, как это сделать в тех случаях, когда никакой другой вариант не подходит для вашего конкретного случая использования. Наконец, мы обсудим, почему вам следует избегать изменения объектов pandas при их повторении.
Вам действительно нужно перебирать строки?
Как подчеркивается в официальной документации pandas, итерация через DataFrames очень неэффективна, и ее обычно можно избежать. Обычно новички в pandas не знакомы с концепцией векторизации и не знают, что большинство операций в pandas должны (и могут) выполняться в неитеративном контексте.
Прежде чем пытаться перебирать объекты pandas, вы должны сначала убедиться, что ни один из приведенных ниже вариантов не соответствует потребностям вашего варианта использования:
- Векторизация вместо итерации: pandas поставляется с богатым набором встроенных методов, производительность которых оптимизирована. Большинство операций потенциально можно выполнить с помощью одного из этих методов. Кроме того, вы даже можете взглянуть на
numpy
и проверить, могут ли какие-либо из его функций использоваться в вашем контексте. - Применение функции к строкам. Распространенным требованием является применение функции к каждой строке, которая предназначена для работы, скажем, только с одной строкой за раз, а не со всем DataFrame или Series. В таких случаях всегда лучше использовать метод
apply()
вместо итерации по объекту pandas. Для получения дополнительной информации вы можете обратиться к этому разделу документации pandas, в котором объясняется, как применить свои собственные или другие функции библиотеки к объектам pandas. - Итерационные манипуляции: если вам нужно выполнить итеративные манипуляции, и в то же время производительность вызывает беспокойство, вам, возможно, придется взглянуть на cython или numba. Для получения дополнительной информации об этих концепциях вы можете прочитать этот раздел документации pandas .
- Печать DataFrame: если вы хотите распечатать DataFrame, просто используйте метод
DataFrame.to_string()
, чтобы отобразить DataFrame в табличный вывод, удобный для консоли.
Итерация по строкам DataFrame
Если ни один из вышеперечисленных вариантов не сработает для вас, вы все равно можете перебирать объекты pandas. Вы можете сделать это, используя либо встроенные iterrows()
, либо встроенные методы itertuples()
.
Прежде чем увидеть оба метода в действии, давайте создадим пример DataFrame, который мы будем использовать для перебора.
import pandas as pd
df = pd.DataFrame({
'colA': [1, 2, 3, 4, 5],
'colB': ['a', 'b', 'c', 'd', 'e'],
'colC': [True, True, False, True, False],
})
print(df)
colA colB colC
0 1 a True
1 2 b True
2 3 c False
3 4 d True
4 5 e False
pandas.DataFrame.iterrows()
используется для перебора строк DataFrame в виде пар (index, Series). Обратите внимание, что этот метод не сохраняет поперечные строки dtypes из-за того, что этот метод преобразует каждую строку в Series. Если вам нужно сохранить dtypes объекта pandas, вы должны вместо этого использовать метод itertuples().
for index, row in df.iterrows():
print(row['colA'], row['colB'], row['colC'])
1 a True
2 b True
3 c False
4 d True
5 e False
pandas.DataFrame.itertuples()
используется для перебора строк DataFrame как именованных кортежей. В целом itertuples() быстрее по сравнению с iterrows().
for row in df.itertuples():
print(row.colA, row.colB, row.colC)
1 a True
2 b True
3 c False
4 d True
5 e False
Изменение при переборе строк
На этом этапе важно подчеркнуть, что вы никогда не должны изменять фрейм данных или серию pandas, которые вы повторяете. В зависимости от типов данных вашего объекта pandas итератор может возвращать копию объекта, а не представление. В этом случае запись чего-либо в копию не даст желаемого эффекта.
Например, предположим, что мы хотим удвоить значения каждой строки в colA
. Итеративный подход не поможет:
for index, row in df.iterrows():
row['colA'] = row['colA'] * 2
print(df)
colA colB colC
0 1 a True
1 2 b True
2 3 c False
3 4 d True
4 5 e False
В аналогичных случаях использования вместо этого следует использовать метод apply()
.
df['colA'] = df['colA'].apply(lambda x: x * 2)
print(df)
colA colB colC
0 2 a True
1 4 b True
2 6 c False
3 8 d True
4 10 e False
Последние мысли
В сегодняшней статье мы обсудили, почему важно избегать итеративных подходов при работе с объектами pandas и отдавать предпочтение векторизованному или действительно любому другому подходу, который подходит для вашего конкретного случая использования.
pandas поставляется с богатым набором встроенных методов, которые оптимизированы для работы с большими объектами pandas, и вы всегда должны отдавать предпочтение им по сравнению с любым другим итеративным решением. Если вы все еще хотите / должны перебирать DataFrame или Series, вы можете использовать методы iterrows()
или itertuples()
.
Наконец, мы обсудили, почему вы всегда должны избегать изменения объекта pandas, который вы перебираете, поскольку это может работать не так, как ожидалось.