Ввод кода оператора Excel IF в Python - PullRequest
0 голосов
/ 07 декабря 2018

Я новичок в Python и использую Excel.Я хочу ввести заявления IF из Excel.До сих пор я использовал xrld для импорта своих листов (ууу!).

Я знаю, что для Excel у нас есть:

IF(logical_test, [value_if_true], [value_if_false])

Для Python я хочу показать, что если значение, A <0, то возвести его в квадрат, а если значение A> 0 (ложь), тогда кубик это.

Для Excel это:

IF(A<0, [A^2], [A^3])

Кроме того, это можно сделать для значений в нескольких столбцах в Python?Для Excel я должен сделать каждый столбец отдельно, но просто перетащите курсор с помощью основного уравнения вниз.

1 Ответ

0 голосов
/ 07 декабря 2018

Вот (не исчерпывающий) список способов сделать это в Python.Pandas, если вы знакомы с ней, - это библиотека для обработки и анализа данных.NumPy - это математическая вычислительная среда, которую интенсивно использует pandas.

A pandas.DataFrame концептуально очень похож на лист Excel.Это очень гибкая структура сбора / данных.Давайте построим DataFrame с одним столбцом:

>>> import numpy as np
>>> import pandas as pd
>>> df = pd.DataFrame({'a': np.random.randn(10)})
>>> df
          a
0  0.829202
1 -2.722945
2  0.877674
3  0.981782
4  0.398093
5 -0.593295
6  0.871504
7  0.439916
8  1.026697
9 -0.063484

Я использовал np.random.randn для генерации последовательности случайных чисел.

Обратите внимание, что если у вас нетДоступ к сторонним библиотекам, вы также можете хранить эти данные в списке или другой встроенной коллекции.Тем не менее, Pandas - лучший инструмент для этой работы, IMO.

Пример NumPy

Давайте рассмотрим решение NumPy.Мы можем использовать numpy.where (сокращенно np.where), чтобы работать в основном так же, как Excel IF, к которому вы привыкли:

>>> calc = np.where(df['a'] < 0, df['a'] ** 2, df['a'] ** 3)
>>> calc
array([5.70138715e-01, 7.41442961e+00, 6.76083380e-01, 9.46335721e-01,
       6.30887662e-02, 3.51999052e-01, 6.61924036e-01, 8.51350238e-02,
       1.08224773e+00, 4.03018586e-03])

Теперь мы можем назначить calc, NumPyмассив, обратно к DataFrame df, если нам нравится:

>>> df['calc'] = calc
>>> df
          a      calc
0  0.829202  0.570139
1 -2.722945  7.414430
2  0.877674  0.676083
3  0.981782  0.946336
4  0.398093  0.063089
5 -0.593295  0.351999
6  0.871504  0.661924
7  0.439916  0.085135
8  1.026697  1.082248
9 -0.063484  0.004030

Пример Pure-Python:

>>> calc = [x ** 2 if x < 0 else x ** 3 for x in df['a']]
>>> calc
[0.5701387154526354, 7.414429614316651, 0.6760833798456796, 0.9463357209355919, 0.0630887661523053, 0.3519990516487755, 0.6619240363210077, 0.08513502375096661, 1.0822477332767624, 0.004030185858203847]
>>> df['calc'] = calc
>>> df
          a      calc
0  0.829202  0.570139
1 -2.722945  7.414430
2  0.877674  0.676083
3  0.981782  0.946336
4  0.398093  0.063089
5 -0.593295  0.351999
6  0.871504  0.661924
7  0.439916  0.085135
8  1.026697  1.082248
9 -0.063484  0.004030

Этот пример чистого Python использует то, что обычно называют «троичным»«оператор - это x ** 2 if x < 0 else x ** 3 материал.Эта строка - просто более лаконичный, «питонский» способ сделать это:

>>> calc = []
>>> for x in df['a']:
...     if x < 0:
...             calc.append(x ** 2)
...     else:
...             calc.append(x ** 3)
... 
>>> calc
[0.5701387154526354, 7.414429614316651, 0.6760833798456796, 0.9463357209355919, 0.0630887661523053, 0.3519990516487755, 0.6619240363210077, 0.08513502375096661, 1.0822477332767624, 0.004030185858203847]

Вы часто будете видеть первый подход - «понимание списка» - потому что он более лаконичен, чем последний.Однако с точки зрения вывода они эквивалентны.

Мы также можем проверить эти подходы с точки зрения синхронизации:

>>> import time
>>> N = 100000
>>> 
>>> def test_numpy():
...     t0 = time.time()
...     for _ in range(N):
...         calc = np.where(df['a'] < 0, df['a'] ** 2, df['a'] ** 3)
...     t1 = time.time()
...     return t1 - t0
... 
>>> def test_list():
...     t0 = time.time()
...     for _ in range(N):
...         calc = [x ** 2 if x < 0 else x ** 3 for x in df['a']]
...     t1 = time.time()
...     return t1 - t0
... 
>>> test_numpy()
34.89216589927673
>>> test_list()
1.9015109539031982

Кажется, что подход list немного быстрее,Если взглянуть немного глубже, используя библиотеку dis, мы увидим, что подход np.where имеет немного больше издержек с точки зрения выполняемых операций:

>>> import dis
>>> dis.dis("np.where(df['a'] < 0, df['a'] ** 2, df['a'] ** 3)")
  1           0 LOAD_NAME                0 (np)
              2 LOAD_ATTR                1 (where)
              4 LOAD_NAME                2 (df)
              6 LOAD_CONST               0 ('a')
              8 BINARY_SUBSCR
             10 LOAD_CONST               1 (0)
             12 COMPARE_OP               0 (<)
             14 LOAD_NAME                2 (df)
             16 LOAD_CONST               0 ('a')
             18 BINARY_SUBSCR
             20 LOAD_CONST               2 (2)
             22 BINARY_POWER
             24 LOAD_NAME                2 (df)
             26 LOAD_CONST               0 ('a')
             28 BINARY_SUBSCR
             30 LOAD_CONST               3 (3)
             32 BINARY_POWER
             34 CALL_FUNCTION            3
             36 RETURN_VALUE
>>> dis.dis("[x ** 2 if x < 0 else x ** 3 for x in df['a']]")
  1           0 LOAD_CONST               0 (<code object <listcomp> at 0x10fdcd1e0, file "<dis>", line 1>)
              2 LOAD_CONST               1 ('<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_NAME                0 (df)
              8 LOAD_CONST               2 ('a')
             10 BINARY_SUBSCR
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...