2017-09-22 9 views
1

私は最近Pythonを分析の主なツールとしてマイグレーションしましたが、私は最初にそれを複製できるようにしたいと考えています。 &最後にSASに見られる機能SASコードは次のようになります。SASの最初と最後の機能をPythonで複製

data data.out; 
    set data.in; 
    if first.ID then flag = 1; 
    if last.ID then flag = 1; 
run; 

出力は次のようになります。

ID  flag 
AAAA 1 
AAAA 0 
AAAA 0 
AAAA 1 
BBBB 1 
BBBB 0 
BBBB 0 
BBBB 1 
CCCC 1 
CCCC 0 
CCCC 1 

Pythonでこれを行う方法についてのアイデアはありますか?あなたのpythonを使用して数値を計算処理している場合

+1

ここで 'pandas'やプレーンなPythonを使っていますか? –

+0

この関数はrespには何を使用しますか?それはどこに便利ですか? SASの –

+0

は、groupbyの最初と最後の行を識別するだけです。機能は基本的にパンダでグループバイをしているとき暗黙のうちに、私の経験では決して必要ではありません(ほとんど?) – JohnE

答えて

3

、事のこのタイプは、通常pandasを使用して行われます:あなたはCSVファイルを持っていると仮定すると

pip install pandas 

、あなたはを使用してデータをロードすることができます。私はあなたの意見を前提にしないので、ドキュメントを見てください。データフレームをロードしたら、続行することができます。

import pandas 

df = pd.read_csv('file.csv') 
df 

     ID 
0 AAAA 
1 AAAA 
2 AAAA 
3 AAAA 
4 BBBB 
5 BBBB 
6 BBBB 
7 BBBB 
8 CCCC 
9 CCCC 
10 CCCC 

df['flag'] = ((df.ID != df.ID.shift()) | (df.ID != df.ID.shift(-1))).astype(int) 
df 
     ID flag 
0 AAAA  1 
1 AAAA  0 
2 AAAA  0 
3 AAAA  1 
4 BBBB  1 
5 BBBB  0 
6 BBBB  0 
7 BBBB  1 
8 CCCC  1 
9 CCCC  0 
10 CCCC  1 

またnp.where(ブラッド・ソロモンから感謝の提案)を使用してこれを行うことができます:

df['flag'] = np.where((df.ID != df.ID.shift()) \ 
        | (df.ID != df.ID.shift(-1)), 1, 0) 
df 
     ID flag 
0 AAAA  1 
1 AAAA  0 
2 AAAA  0 
3 AAAA  1 
4 BBBB  1 
5 BBBB  0 
6 BBBB  0 
7 BBBB  1 
8 CCCC  1 
9 CCCC  0 
10 CCCC  1 
2

パンダを使用する:

import pandas as pd 
import numpy as np 
df = pd.DataFrame(['AAAA', 'AAAA', 'AAAA', 'AAAA', 
        'BBBB', 'BBBB', 'BBBB', 'BBBB', 'CCCC', 'CCCC', 'CCCC',], 
        columns=['ID']) 

def firstlast(a): 
    # For each character grouping set, create a 1d array of 0s padded 
    #  with 1s, equal to length of the group. 
    a = np.zeros(len(a)-2) 
    a = np.pad(a, (1,1), 'constant', constant_values=(1,1)) 
    return a 

df['flag'] = (s.groupby(s).apply(firstlast).apply(pd.Series).stack() 
        .astype(int).values) 

print(df) 
     ID flag 
0 AAAA  1 
1 AAAA  0 
2 AAAA  0 
3 AAAA  1 
4 BBBB  1 
5 BBBB  0 
6 BBBB  0 
7 BBBB  1 
8 CCCC  1 
9 CCCC  0 
10 CCCC  1 

がロジックに@cᴏʟᴅsᴘᴇᴇᴅからのビットを盗みます(これは上記のソリューションよりはるかに賢いですが)numpy.where

ids = df.ID 
df['flag'] = np.where((ids!=ids.shift(1)) | (ids!=ids.shift(-1)), 1, 0) 

print(df) 
     ID flag 
0 AAAA  1 
1 AAAA  0 
2 AAAA  0 
3 AAAA  1 
4 BBBB  1 
5 BBBB  0 
6 BBBB  0 
7 BBBB  1 
8 CCCC  1 
9 CCCC  0 
10 CCCC  1 
+3

ちょうど、SASではBY文がファイル内で見つかった順序に従ってグループを処理し、連続したグループのみを扱うことに注意してください(例えばAAA BBB AAAは3つのグループですが、 'df.groupby'は2つのグループを考慮します)...それはおそらくここで重要なことではなく、注目に値する... –

1

私はこのように感じるが、当然GROUPBYの概念であり、理想的には(多くのため、以下の本の簡単な説明を参照)のいずれかのシフトベースのアプローチと間違って何も確かにありませんが、GROUPBYベースのアプローチを使用します。

df.loc[ df.groupby('ID',as_index=False).nth([0,-1]).index, 'flag' ] = 1 

nth(0)まず各GROUPBYの行との両方の選択nth([0,-1])nth(-1)最後を選択します。これにより、他の行が欠落したままになり、簡単にfillna(0)で埋め込むことができます。

@JonClementsによるコメントに関して
df.flag = df.flag.fillna(0).astype(int) 

     ID flag 
0 AAAA  1 
1 AAAA  0 
2 AAAA  0 
3 AAAA  1 
4 BBBB  1 
5 BBBB  0 
6 BBBB  0 
7 BBBB  1 
8 CCCC  1 
9 CCCC  0 
10 CCCC  1 

、シフトのアプローチを使用して、一方の順序を並べ替えるために不変回答にGROUPBY結果を使用して並べ替え順序に依存することに注意してください(特定に応じて、好ましいかもしれないいずれもの状況)。

関連する問題