2017-08-01 7 views
0

銀行クライアントの日次データを処理する必要があります。 2つのクライアントのサンプルデータがdfデータフレームに読み込まれます。pandasはコンプレックスを使用してデータフレームを更新します。条件

ローリングバランスとデータ保持のために、各クライアントを別々に処理する必要があるため、account_id + bus_dtにインデックスを作成し、このインデックスでdfをソートします。 日付と日付のバランスを計算する必要があるので、前の行の値が必要です。

最初の行の各アカウントについて、すべての値を特定の値にリセットする必要があるため、cumcount()関数を使用して各グループにシーケンス番号を作成します。

Iが配列= 0が、しかし私は、シーケンス> 0及び他の基準が必要とされる行を更新することができないDFのすべての行を更新することができる午前: I条件の最初の部分で選択された行にアクセスすることができる:

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

私はここ状態の第二部で選択された行にアクセスすることができる:

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

しかし、私は一度に両方のcriteriasで所望の行にアクセスすることができない。

012エラーと

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基準を満たすデータフレームのすべての行をアップレートすることができますか?

# 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を複製しようとしているが、私は願って、私がここに書いたものと同じであるロジックを実装しました。上記のすべてのアクションは、データフレーム全体で「一度に」実行することができ、行単位の反復を可能にするためのデータの準備であるため、不十分であるか適切に実装されていないことを示唆しています。あなたが代わりにandのため&演算子を使用する必要があり

答えて

1

&は、データフレーム内の述語が選択一緒にANDに使用されます。

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

はまた、あなたがする必要がある注意してください各述語のまわりに()を置く。

+0

ボーナスに関する質問:私はこれらの値に 'max(df ['prev_balance'] - df ['balance']、0)'の結果を割り当てる必要がありますが、私は集計関数としてimterpretedしていると思います。 error 'ValueError:Seriesの真理値はあいまいです。 'df ['prev_balance'] - df ['balance']'のみをうまく動作させるには、a.empty、a.bool()、a.item()、a.any()、a.all() 。しかし、ここで2つの数字の最大値を割り当てる方法は? –

1

df.loc[(df['seq'] > 0) & (df['bus_dt'] - df['prev_bus_dt'] <= pd.Timedelta('2 days')) , 'balance'] 
関連する問題