numpy 向量化(累积变量)

numpy vectorization(accumulate variable)

我有一个数据框。 包含几列。它看起来像这样:

A B C D
1 10 a Nan
2 11 b Nan
3 12 c Nan

所以如果我在 C 列中有 'b',我应该做 A+B。 在其他情况下 A*B。 但是有了它,我就有了积累价值的变量(你会看到代码,它会很清楚)。 所以我写了这段代码

z = 0
for i, row in df.iterrows():
    a = df['A']
    b = df['B']
    c = df['C']
    if c == 'b':
        d = a + b + z
        z = z + 2
    else:
        d = a*b
    df.at[i, 'D'] = d

但是 df.iterrows() 是反模式,我应该在我的代码中避免使用这个字符串。 因为如果我的数据集增加,那将是一个问题 我曾尝试使用矢量化,但我不知道如何累积。 代码如下所示:

z = 0
con = (df['C'] == 'b',
      df['C'] != 'b')
choise = (
    (df['A'] + dfs['B'], z + 2),
    (df['A'] * dfs['B'], )
)

dfs['D'], z = np.select(con, choise)

有人可以帮我吗?如何累加变量z?

为什么不呢:

z = 0
new_D = []

for row in df.itertuples():
    if row.C == 'b':
        new_D.append(row.A + row.B + z)
        z += 2
    else:
        new_D.append(row.A * row.B)

df['D'] = new_D

我对第一个代码块应该做什么感到困惑:

z = 0
for i, row in df.iterrows():
    a = df['A']
    b = df['B']
    c = df['C']
    if c == 'b':
        d = a + b + z
        z = z + 2
    else:
        d = a*b
    df.at[i, 'D'] = d

irows是迭代变量,但是你不使用rows,只在最后使用i来设置原来的东西df.

你明白 iterrows 的作用吗(除了它是一个“反模式”):

看小df:

In [168]: df = pd.DataFrame(np.arange(6).reshape(2,3), columns=['A','B','C'])
In [169]: df
Out[169]: 
   A  B  C
0  0  1  2
1  3  4  5

然后 iterrows 打印大量照片:

In [170]: for i, row in df.iterrows():
     ...:     print('==========')
     ...:     print(i, type(row));print(row)
     ...:     a = df['A']
     ...:     print('a', type(a));print(a)
     ...: 
==========
0 <class 'pandas.core.series.Series'>
A    0
B    1
C    2
Name: 0, dtype: int64
a <class 'pandas.core.series.Series'>
0    0
1    3
Name: A, dtype: int64
==========
1 <class 'pandas.core.series.Series'>
A    3
B    4
C    5
Name: 1, dtype: int64
a <class 'pandas.core.series.Series'>
0    0
1    3
Name: A, dtype: int64

rows 是一个 pandas 系列(例如数据框的一列),数据来自一行。就像把行变成列一样。 df['A'] 也是一个系列,但是 df 列之一。

整个:

a = df['A']
b = df['B']
c = df['C']
if c == 'b':
    d = a + b + z
    z = z + 2
else:
    d = a*b

代码块正在处理框架的列 - 整列,而不是一行中的值。在循环中一次又一次地重复这些计算是没有意义的。

c 是一个系列,所以 if c=='b 会引发错误。使用我示例中的 a

'==' 测试产生一个系列 在 [172] 中:a==3 输出[172]: 0 错误 1 正确 名称:A,数据类型:bool

if 中使用该系列会引发 ambiguity 错误。

In [173]: if a==3: print('yes')
Traceback (most recent call last):
  File "<ipython-input-173-1ccc6f02d1f6>", line 1, in <module>
    if a==3: print('yes')
  File "/usr/local/lib/python3.8/dist-packages/pandas/core/generic.py", line 1537, in __nonzero__
    raise ValueError(
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

因此您对 iterrows 的使用不仅仅是“anti-pattern”。使用的代码完全错误。我详细介绍了很多,因为我认为您需要的不仅仅是“快速”回答。您需要了解您的代码中发生了什么。