Применение значений к DataFrame без использования цикла for - PullRequest
2 голосов
/ 23 мая 2019

Я ищу более быстрый способ применения значений к столбцу в DataFrame.Значение основано на двух значениях True and False в первом и втором столбце.Это мое текущее решение:

df['result'] = df.check1.astype(int)

for i in range(len(df)):
    if df.result[i] != 1:
        df.result[i] = df.result.shift(1)[i] + df.check2[i].astype(int)

, которое дает этот результат:

    check1  check2  result
0   True    False   1
1   False   False   1
2   False   False   1
3   False   False   1
4   False   False   1
5   False   False   1
6   False   True    2
7   False   False   2
8   False   True    3
9   False   False   3
10  False   True    4
11  False   False   4
12  False   True    5
13  False   False   5
14  False   True    6
15  False   False   6
16  False   True    7
17  False   False   7
18  False   False   7
19  False   False   7
20  False   True    8
21  False   False   8
22  False   True    9
23  True    False   1
24  False   False   1

Таким образом, третий столбец должен быть числом, основанным на значении в строке над ним.Если check1 - True, число должно вернуться к 1. Если check2 - true, к номеру необходимо добавить 1.В противном случае число остается неизменным.

Текущий код в порядке, но это занимает слишком много времени, так как мне нужно применить это к DataFrame с прибл.70 000 строк.Я почти уверен, что это можно улучшить (я предполагаю использовать функцию apply, но я не уверен).
Есть идеи?

Ответы [ 2 ]

3 голосов
/ 23 мая 2019

Использование pandas.DataFrame.groupby.cumsum:

import pandas as pd

df['result'] = df.groupby(df['check1'].cumsum())[['check1', 'check2']].cumsum().sum(1)

Или предложение Дана:

df['result'] = df.groupby(df['check1'].cumsum())['check2'].cumsum().add(1)

Вывод:

    check1  check2  result
0     True   False     1.0
1    False   False     1.0
2    False   False     1.0
3    False   False     1.0
4    False   False     1.0
5    False   False     1.0
6    False    True     2.0
7    False   False     2.0
8    False    True     3.0
9    False   False     3.0
10   False    True     4.0
11   False   False     4.0
12   False    True     5.0
13   False   False     5.0
14   False    True     6.0
15   False   False     6.0
16   False    True     7.0
17   False   False     7.0
18   False   False     7.0
19   False   False     7.0
20   False    True     8.0
21   False   False     8.0
22   False    True     9.0
23    True   False     1.0
24   False   False     1.0
0 голосов
/ 23 мая 2019

Вы хотите перебрать кадр данных, используя значение предыдущей строки. В этом случае наиболее эффективный способ состоит в прямой итерации базовых массивов numpy:

df = pd.read_fwf(io.StringIO(t))

df['result'] = df.check1.astype(int)

res = df['result'].values
c1 = df['check1'].values
c2 = df['check2'].values
old = -1
for i in range(len(df)):
    if res[i] != 1:
        res[i] = old + int(c2[i])
    old = res[i]

Это отлично работает, потому что массивы numpy являются изменяемыми типами, поэтому изменения отражаются в кадре данных.

Timeit говорит, что это вдвое быстрее, чем оригинальное решение от @ Chris's, и еще в 1,5 раза быстрее после улучшения @ Dan.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...