2017-09-28 274 views
1

我想要完成的是一個條件檢查,它查看數量列中的值。 如果df ['amount']中的值小於200k,則不做任何操作。 如果df ['amount']中的值大於或等於200k,則將相應值替換爲月或36.00的值,具體取決於哪個更大。用條件替換數據幀的值

import pandas as pd 
df['amount'] = [332374.00, 22250.75, 45282.10, 339720.00, 1100.00, 40000.00, 15000.00, 207820.00, 497432.00] 
df['months'] = [18.00, 17.00, 16.00, 46.00, 14.00, 13.00, 13.00, 13.00, 12.00] 
df['checks'] = [1.00, 0.00, 0.00, 1.00, 0.00, 0.00, 0.00, 1.00, 1.00] 

所需的輸出是一個看起來像這樣的數據集。

amount  months checks 
332374.00 36.00 1.00 
22250.75 17.00 0.00 
45282.10 16.00 0.00 
339720.00 46.00 1.00 
1100.00  14.00 0.00 
40000.00 13.00 0.00 
15000.00 13.00 0.00 
207820.00 36.00 1.00 
497432.00 36.00 1.00 

回答

3

您可以只使用loc找到實例,其中量超過20萬的門檻,其中個月低於36。然後,只需設置這些值36

df.loc[(df['amount'] >= 200000) & (df['months'] < 36), 'months'] = 36 
>>> df 
     amount months checks 
0 332374.00  36  1 
1 22250.75  17  0 
2 45282.10  16  0 
3 339720.00  46  1 
4 1100.00  14  0 
5 40000.00  13  0 
6 15000.00  13  0 
7 207820.00  36  1 
8 497432.00  36  1 

時序

使用assign會速度較慢,因爲您必須複製整個數據幀,然後分配新列。使用loc會更快。

下面是關於這個小數據集的時序:

%timeit df.assign(months=df.months.mask(df.amount.ge(2E5), np.maximum(df.months, 36))) 
# 1000 loops, best of 3: 1.01 ms per loop 

%timeit df.loc[(df['amount'] >= 200000) & (df['months'] < 36), 'months'] = 36 
# 1000 loops, best of 3: 838 µs per loop 
+0

好的解釋!我經常使用'assign',這樣我就不會覆蓋我的數據框。但這是你重寫當前數據幀的重要原因。 – piRSquared

+0

謝謝!這是爲我工作的解決方案。我只是想對你們倆表示感謝,並感謝你們的幫助。非常酷的實現。 – mnickey

3

pd.Series.mask可屏蔽在cond參數傳遞的True值的位置的一系列值。您也可以傳遞other參數來提供值來替換被屏蔽的值。我使用np.maximum來生成other值。

df.assign(months=df.months.mask(df.amount.ge(2E5), np.maximum(df.months, 36))) 

     amount months checks 
0 332374.00 36.0  1.0 
1 22250.75 17.0  0.0 
2 45282.10 16.0  0.0 
3 339720.00 46.0  1.0 
4 1100.00 14.0  0.0 
5 40000.00 13.0  0.0 
6 15000.00 13.0  0.0 
7 207820.00 36.0  1.0 
8 497432.00 36.0  1.0 

參見pd.Series.where因爲我們可以用執行相同的任務:

df.assign(months=df.months.where(df.amount.lt(2E5), np.maximum(df.months, 36))) 

     amount months checks 
0 332374.00 36.0  1.0 
1 22250.75 17.0  0.0 
2 45282.10 16.0  0.0 
3 339720.00 46.0  1.0 
4 1100.00 14.0  0.0 
5 40000.00 13.0  0.0 
6 15000.00 13.0  0.0 
7 207820.00 36.0  1.0 
8 497432.00 36.0  1.0 

我們也可以用同樣的邏輯,但利用numpy.where

a = df.amount.values 
m = df.months.values 
df.assign(months=np.where(a < 2E5, m, np.maximum(m, 36))) 

     amount months checks 
0 332374.00 36.0  1.0 
1 22250.75 17.0  0.0 
2 45282.10 16.0  0.0 
3 339720.00 46.0  1.0 
4 1100.00 14.0  0.0 
5 40000.00 13.0  0.0 
6 15000.00 13.0  0.0 
7 207820.00 36.0  1.0 
8 497432.00 36.0  1.0 
執行此任務
+0

非常感謝你。儘管我採用了其他解決方案,但我非常感謝您的時間和詳細的解釋。我將不得不閱讀更多的分配和掩碼。 – mnickey

+0

沒問題,我很高興你找到了答案。 – piRSquared