[英]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 次循環)然而,更多的數據可以觀察到真正的好處。 如果您使數據集僅大 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 次循環)差異隨着數據集的大小而增長。
我在 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.