В первую очередь хочется сказать, что обходить датафрейм не самая лучшая затея из-за плохой производительности и гораздо лучше будет воспользоваться альтернативными методами в виде функции apply (рассмотрим ниже). Если же все-таки потребовалось проитерироваться по строкам в DataFrame, то приведу код ниже. Однако использовать его стоит лишь для небольших дата-сетов.
import pandas as pd
dataframe_from_list = [[1,2], [3,4], [10,20]]
df = pd.DataFrame(dataframe_from_list, columns=['col1', 'col2'])
for index, row in df.iterrows():
print(index, row)
print(row['col1'], row['col2'], row['col1'] + row['col2']) В данном примере использовалась функция iterrows для обхода датафрейма. Для обращения к колоночным значениям в строке используется row[‘название_колонки’].
А теперь давайте подумаем, зачем нам итерироваться по датафрейму? Самое очевидно — это взять некоторые колоночные значения из строки и подсчитать некоторую функцию.
Но это можно сделать и с помощью apply метода с указанием направления по оси x:
result = df.apply(lambda row: row['col1'] + row['col2'], axis=1) print(result) # 3, 7, 30
Соответсвенно, вместо lambda функции можно поставить свою, или в простом случае использовать оптимизированные numpy функции, например np.sum
Ну а на последок, давайте представим что у нас большое кол-во строк, сравнимое с миллионом, и нам надо подсчитать некую функцию. Проблема в том, что pandas вычисляет apply в один процесс, а все современные процессоры имют несколько ядер. Поэтому необходимо распараллелить apply функцию для оптимального расчета. Для распараллеливания и быстрого расчета функции по датафрейму воспользуемя функцией ниже:
from multiprocessing import Pool
import numpy as np
# для примера возьмем функцию суммы по строке, приведенную выше
def calculate_sum_column(df):
df['sum_column'] = df.apply(lambda row: row['col1'] + row['col2'], axis=1)
return df
# в данном примере расспараллеливаем на восемь потоков. Будьте аккуратны - при распараллеливании тратится больше оперативной памяти
def parallelize_dataframe(df, func):
a,b,c,d,e,f,g,h = np.array_split(df, 8)
pool = Pool(8)
some_res = pool.map(func, [a,b,c,d,e,f,g,h])
df = pd.concat(some_res)
pool.close()
pool.join()
return df
# имитация большого датасета
df = pd.concat([df, df, df], ignore_index=True)
df = parallelize_dataframe(df, calculate_sum_column)
print(df.head(10)) С помощью данного гибкого «многоядерного» подхода можно многократно ускорить обход датафрейма и вычислить необходимую функцию