Мой ответ будет сосредоточен на КОГДА мы можем использовать while / for-else.
На первый взгляд кажется, что при использовании
while CONDITION:
EXPRESSIONS
print 'ELSE'
print 'The next statement'
и
while CONDITION:
EXPRESSIONS
else:
print 'ELSE'
print 'The next statement'
Поскольку оператор print 'ELSE'
, как представляется, всегда выполняется в обоих случаях (оба, когда цикл while
закончен или не запущен).
Тогда это отличается только тогда, когда оператор print 'ELSE'
не будет выполнен. Когда внутри [code] while
In [17]: i = 0
In [18]: while i < 5:
print i
if i == 2:
break
i = i +1
else:
print 'ELSE'
print 'The next statement'
....:
0
1
2
The next statement
имеется break
, есть break
, если он отличается от:
In [19]: i = 0
In [20]: while i < 5:
print i
if i == 2:
break
i = i +1
print 'ELSE'
print 'The next statement'
....:
0
1
2
ELSE
The next statement
return
, поскольку он делает тот же эффект для двух вышеприведенных случаев.
exception raise также не вызывает различий, потому что когда он поднимается, где следующий код будет выполнен, в обработчике исключений (кроме блока), код в else
или сразу после того, как предложение while
не будет выполнено.
Вы можете вывести из вашего df и вызывать count
передачу axis=1
:
In [24]:
df['count'] = df[list('abcde')].count(axis=1)
df
Out[24]:
Close a b c d e Time count
2015-12-03 2051.25 5 4 3 1 1 05:00:00 5
2015-12-04 2088.25 5 4 3 1 NaN 06:00:00 4
2015-12-07 2081.50 5 4 3 NaN NaN 07:00:00 3
2015-12-08 2058.25 5 4 NaN NaN NaN 08:00:00 2
2015-12-09 2042.25 5 NaN NaN NaN NaN 09:00:00 1
TIMINGS
In [25]:
%timeit df[['a', 'b', 'c', 'd', 'e']].apply(lambda x: sum(x.notnull()), axis=1)
%timeit df.drop(['Close', 'Time'], axis=1).count(axis=1)
%timeit df[list('abcde')].count(axis=1)
100 loops, best of 3: 3.28 ms per loop
100 loops, best of 3: 2.76 ms per loop
100 loops, best of 3: 2.98 ms per loop
apply
является самым медленным, который не является неожиданно, версия drop
немного быстрее, но семантически я предпочитаю просто передавать список интересующих количеств и вызывать count
для удобочитаемости
Хмм, я продолжаю получать различные тайминги сейчас:
In [27]:
%timeit df[['a', 'b', 'c', 'd', 'e']].apply(lambda x: sum(x.notnull()), axis=1)
%timeit df.drop(['Close', 'Time'], axis=1).count(axis=1)
%timeit df[list('abcde')].count(axis=1)
%timeit df[['a', 'b', 'c', 'd', 'e']].count(axis=1)
100 loops, best of 3: 3.33 ms per loop
100 loops, best of 3: 2.7 ms per loop
100 loops, best of 3: 2.7 ms per loop
100 loops, best of 3: 2.57 ms per loop
] БОЛЬШЕ ВРЕМЕНИ
In [160]:
%timeit df[['a', 'b', 'c', 'd', 'e']].apply(lambda x: sum(x.notnull()), axis=1)
%timeit df.drop(['Close', 'Time'], axis=1).count(axis=1)
%timeit df[list('abcde')].count(axis=1)
%timeit df[['a', 'b', 'c', 'd', 'e']].count(axis=1)
%timeit df[list('abcde')].notnull().sum(axis=1)
1000 loops, best of 3: 1.4 ms per loop
1000 loops, best of 3: 1.14 ms per loop
1000 loops, best of 3: 1.11 ms per loop
1000 loops, best of 3: 1.11 ms per loop
1000 loops, best of 3: 1.05 ms per loop
Кажется, что тестирование для notnull
и суммирование (поскольку notnull
приведет к созданию булевой маски) быстрее на этом наборе данных
Вкл. строка 50k df, последний метод немного быстрее:
In [172]:
%timeit df[['a', 'b', 'c', 'd', 'e']].apply(lambda x: sum(x.notnull()), axis=1)
%timeit df.drop(['Close', 'Time'], axis=1).count(axis=1)
%timeit df[list('abcde')].count(axis=1)
%timeit df[['a', 'b', 'c', 'd', 'e']].count(axis=1)
%timeit df[list('abcde')].notnull().sum(axis=1)
1 loops, best of 3: 5.83 s per loop
100 loops, best of 3: 6.15 ms per loop
100 loops, best of 3: 6.49 ms per loop
100 loops, best of 3: 6.04 ms per loop
df['Count'] = df[['a', 'b', 'c', 'd', 'e']].apply(lambda x: sum(x.notnull()), axis=1)
In [1254]: df
Out[1254]:
Close a b c d e Time Count
2015-12-03 2051.25 5 4 3 1 1 05:00:00 5
2015-12-04 2088.25 5 4 3 1 NaN 06:00:00 4
2015-12-07 2081.50 5 4 3 NaN NaN 07:00:00 3
2015-12-08 2058.25 5 4 NaN NaN NaN 08:00:00 2
2015-12-09 2042.25 5 NaN NaN NaN NaN 09:00:00 1
Включите список желаемых columns
или просто отпустите два columns
, которые вы не хотите исключать из count - вдоль axis=1
(см. docs) :
df['Count'] = df.drop(['Close', 'Time'], axis=1).count(axis=1)
Close a b c d e Time Count
0 2051.25 5 4 3 1 1 05:00:00 5
1 2088.25 5 4 3 1 NaN 06:00:00 4
2 2081.50 5 4 3 NaN NaN 07:00:00 3
3 2058.25 5 4 3 NaN NaN 08:00:00 3
4 2042.25 5 4 NaN NaN NaN 09:00:00 2