下面是Python中实现这一点的方法列表(并非详尽无遗)。如果你熟悉Pandas,它是一个数据操作和分析库。NumPy是pandas大量使用的一个数学计算框架。在
从概念上讲,pandas.DataFrame与Excel表格非常相似。这是一个非常灵活的收集/数据结构。让我们构造一个只有一列的数据帧:>>> 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生成一个随机数序列。在Note that if you don't have access to third-party libraries, you can also store these data in a list or other built-in collection. Pandas is kind of the best tool, IMO, for this work, however.
NumPy示例
让我们看看一个NumPy解决方案。我们可以使用numpy.where(缩写为np.where)以与Excel基本相同的方式操作IF,您习惯于:
^{pr2}$
现在我们可以将一个NumPy数组calc分配回数据帧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
纯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的东西。这句话只是一种更简洁的“Python”式的表达方式:>>> 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 ( at 0x10fdcd1e0, file "", line 1>)
2 LOAD_CONST 1 ('')
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