2017-08-01 113 views
0

我需要處理銀行客戶每日數據更新數據幀。兩個客戶端的示例數據加載到df數據框中。大熊貓複雜WHERE條件

我需要分別處理每個客戶端,需要一天後迭代天,滾存結餘和保留數據,所以我通過這個指數創建ACCOUNT_ID + bus_dt和排序DF指數。 我需要計算行之間的日期和平衡差異,所以我需要先前的行值。

對於每一個客戶的第一行,我需要的所有值重置爲特定的值,因此我使用cumcount()功能各組中創建序列號。

我能夠更新所有的行中DF其中序列= 0,但是我不能更新的行在需要序列> 0和其他標準: 我可以與其中條件的第一部分訪問所選行:

df.loc[df['seq'] > 0 , 'balance'] 

df.loc[df['bus_dt'] - df['prev_bus_dt'] <= pd.Timedelta('2 days') , 'balance'] 

但我不能與兩個規定 - 在一次訪問所需的行:

我可以的,其中第二條件訪問部分選擇的行

錯誤:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\Ludwik\Python\python-3.5.4rc1-embed-amd64\lib\site-packages\pandas\core\generic.py", line 955, in __nonzero__ 
    .format(self.__class__.__name__)) 
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). 

如何使用其中a> 0 B =什麼?

下面是完整的代碼,以準備數據:

import pandas as pd 
import numpy as np 
# np.array([3] * 4 + [4] * 5 ,dtype='int32') 
# dates = np.array(pd.date_range('20170101', periods=6) + pd.date_range('20170101', periods=5)) 

df1=pd.DataFrame({ 
'account_id': np.array([101] * 7,dtype='int32'), 
'bus_dt': pd.date_range('20170101', periods=7), 
'balance': abs(np.random.randn(7)*100) 
}) 
df2=pd.DataFrame({ 
'account_id': np.array([102] * 10,dtype='int32'), 
'bus_dt': pd.date_range('20170104', periods=10), 
'balance': abs(np.random.randn(10)*100) 
}) 

df1=df1.loc[df1['bus_dt'] != '20170103'] 
df1=df1.loc[df1['bus_dt'] != '20170104'] 

df2=df2.loc[df2['bus_dt'] != '20170111'] 
df2=df2.loc[df2['bus_dt'] != '20170112'] 

df=df1.append(df2) 



df.head() 

# i need to process each account separately and need to iterate day after day, for rolling and retaining data, 
# so i create index on account_id and bus_dt and sort df by this index 
df.set_index(['account_id','bus_dt'], inplace=True, drop=False) 
df.sort_index(ascending=[True,True], inplace=True) 

# i need to calculate date differences between rows, so i need prev row values 
df['prev_bus_dt']=df.groupby(level=0)['bus_dt'].shift(1) 
df['prev_balance']=df.groupby(level=0)['balance'].shift(1) 

#i need to zero first row in each group, so i create sequence in each group to access 0 indexed row in each group 
df['seq']=df.groupby(level=0).cumcount() 
# so I update 
df.loc[df['seq'] == 0, 'prev_bus_dt'] = df['bus_dt'] 
df.loc[df['seq'] == 0, 'prev_balance'] = df['balance'] 

下面是一塊工作我奮鬥着。我如何在符合beow標準的所有數據框行上執行upate操作?

# but when I need to update selected column based on complex where criteria, here starts the problem: 
# all of the below methods do not work 
# option 1 
df.loc[df['seq'] > 0 and df['bus_dt'] - df['prev_bus_dt'] <= pd.Timedelta('2 days'), 'balance']=max(df['prev_balance'] - df['balance'],0) 
# option 2 
df['balance']=np.where(df['seq'] > 0 and df['bus_dt'] - df['prev_bus_dt'] <= pd.Timedelta('2 days'), max(df['prev_balance'] - df['balance'],0), 0) 
# option 3 
df.loc[df['seq'] > 0 and df['bus_dt'] - df['prev_bus_dt'] <= pd.Timedelta('2 days'),'balance'].all()=max(df['prev_balance'] - df['balance'],0) 

我是新來的Python和試圖複製SAS實現的邏輯,我希望,這與我在這裏寫的相同。所有上述行動可以「立即」對整個數據幀進行,並且準備數據,使行通過行迭代,所以我願意接受任何建議,什麼是效率不高或不正確執行。

回答

1

&用於AND一起在一個數據幀謂詞選擇:

df.loc[((df['seq'] > 0) & (df['bus_dt'] - df['prev_bus_dt'] <= pd.Timedelta('2 days'))) , 'balance']

另外請注意,你必須圍繞每個謂詞放置()

+0

獎金的問題:我需要分配到最大的'那些值結果(DF [「prev_balance」] - DF [「平衡」,0)',但我認爲這是imterpreted作爲聚合函數,因爲我得到錯誤'ValueError:一個Series的真值不明確。使用a.empty,a.bool(),a.item(),a.any()或a.all()' 只分配'DF [ 'prev_balance'] - DF [ '平衡']'工作正常。但是,如何在這裏分配兩個數字的最大值? –

1

您需要使用&操作爲,而不是and

df.loc[(df['seq'] > 0) & (df['bus_dt'] - df['prev_bus_dt'] <= pd.Timedelta('2 days')) , 'balance']