簡體   English   中英

編寫嵌套 if 而不是 for if 的任何更好的方法

[英]Any better way to write nested if instead of for an if

我剛剛開始學習 python 所以如果我沒有正確地問這個問題,請忽略或讓我知道。

我有一個 dataframe df

df = pd.DataFrame({'A' : [5,6,0,-4], 'B' : [1,2,3,5]})
一個
5 1
6 2
0 3
-4 5

我想做以下事情:

如果 A 大於 0 則 DO;

----如果 B < 2 那么 NEWVALUE = A * 2

----否則 A = A/2

IF A = 0 then CALC_FIELD = NEWVALUE + 2 # 使用剛剛在上一步創建的NEWVALUE

我正在使用以下“for”和“if”的組合來獲取 output。 但是有沒有更好更有效的方法來做到這一點?

for i in range(df.shape[0]):
    if (df.loc[i, 'A'] > 0) & (df.loc[i, 'B'] < 2): df.loc[i,'NEWVALUE'] =  df.loc[i,'A'] * 2
    if (df.loc[i, 'A'] <= 0): df.loc[i, 'NEWVALUE'] = df.loc[i,'A'] / 2
    if (df.loc[i, 'A'] == 0): df.loc[i, 'CALC_FIELD'] = df.loc[i, 'NEWVALUE'] + 2
**EXPECTED OUTPUT**
|  A | B  | C  | D  |
| -- | -- | -- |--  |
| 5  | 1  | 10 | Nan|
| 6  | 2  | Nan| Nan| 
| 0  | 3  | 0  | 2  |
| -4 | 5  | -2 |Nan | 

我認為您想要的 output 中有錯字。

對於這種計算,我也不會使用for循環。 如果您有很多條件並且想要創建 1 列,我建議使用np.select ,但由於您的目標是創建 2 列,因此一種簡單的方法是使用np.where兩次:

import numpy as np
df['C']= np.where((df['A']>0) & (df['B']<2) ,df['A'].mul(2),df['A'].div(2))
df['D']= np.where(df['A'].eq(0),df['C'].add(2),np.nan)

得到:

df
   A  B     C    D
0  5  1  10.0  NaN
1  6  2   3.0  NaN
2  0  3   0.0  2.0
3 -4  5  -2.0  NaN

只需添加一些現有的好答案 我同意您應該盡可能避免使用 for 循環,因為內置的矢量化操作會更好地擴展。 有關 DataFrame 的迭代次數,請參見此處

np.where的替代方法是僅使用相同的loc邏輯,但使用 boolean 索引*:

df.loc[(df['A'] > 0) & (df['B'] < 2), 'NEWVALUE'] = df['A'] * 2
df.loc[df['A'] <= 0, 'NEWVALUE'] = df['A'] / 2
df.loc[df['A'] == 0, 'CALC_FIELD'] = df['NEWVALUE'] + 2

*我同意其他評論,您可能需要仔細檢查您的邏輯是否按照您的意圖進行; 帖子中並不完全清楚。

在這種嚴重的情況下,這個解決方案實際上比for循環稍微慢一點,有趣的是(使用%%timeit ):

  • for循環:每個循環1.12 毫秒± 69 微秒(平均值 ± 標准偏差。7 次運行,每次 1000 次循環)
  • boolean 分度:每循環2.41 ms ± 47.1 µs(平均值 ± 標准偏差,7 次運行,每次 100 次循環)

然而,更多的數據可以觀察到真正的好處。 如果您使數據集僅大 10 倍:

import pandas as pd

df = pd.DataFrame({'A' : [5,6,0,-4]*10, 'B' : [1,2,3,5]*10})

矢量化索引要快得多:

  • for循環:每個循環10.8 毫秒± 83 微秒(平均值 ± 標准偏差。7 次運行,每次 100 次循環)
  • boolean 分度:每循環2.37 ms ± 37.5 µs(平均值 ± 標准偏差,7 次運行,每次 100 個循環)

差異隨着數據集的大小而增長。

我在 jupyter notebook 中嘗試了相同的代碼片段,得到了所需的 output。

import pandas as pd
df = pd.DataFrame({'A' : [5,6,0,-4], 'B' : [1,2,3,5]})
for i in range(df.shape[0]):
    if (df.loc[i, 'A'] > 0) & (df.loc[i, 'B'] < 2): df.loc[i,'C'] =  df.loc[i,'A'] * 2
    if (df.loc[i, 'A'] <= 0): df.loc[i, 'C'] = df.loc[i,'A'] / 2
    if (df.loc[i, 'A'] == 0): df.loc[i, 'D'] = df.loc[i, 'C'] + 2
df

這給出了預期的 output:

    A   B     C      D
0   5   1   10.0    NaN
1   6   2   NaN     NaN
2   0   3   0.0     2.0
3  -4   5  -2.0     NaN

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM