2017-09-22 1 views
1

Ich habe kürzlich nach Python als mein primäres Werkzeug für die Analyse migriert und ich bin in der Lage, das erste zu replizieren. & zuletzt. Funktionalität in SAS gefunden. Der SAS-Code wäre wie folgt;Replizieren der ersten und letzten Funktionalität von SAS mit Python

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

Die Ausgabe wäre wie folgt;

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

Irgendwelche Ideen, wie man das in Python macht?

+1

Verwenden Sie etwas wie Pandas hier oder schlicht Python? –

+0

Was ist diese Funktion für resp. Wo ist es nützlich? –

+0

in SAS identifiziert es nur die ersten und letzten Zeilen einer groupby. die Funktionalität ist grundsätzlich implizit, wenn man eine groupby in Pandas macht und (fast?) nie in meiner Erfahrung gebraucht wird – JohnE

Antwort

3

Wenn Sie Python und Knirschen Zahlen, diese Art der Sache der Regel erfolgen würde mit pandas verwenden:

pip install pandas 

Angenommen, Sie haben eine CSV-Datei, Sie mit in Ihren Daten geladen werden können . Ich werde keine Annahmen über Ihre Eingaben treffen, also sehen Sie sich bitte die Dokumentation an. Sobald Sie Ihren Datenrahmen geladen haben, können Sie fortfahren.

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 

Sie können auch diese mit np.where (von Brad Solomon geschätzt Vorschlag) zu tun:

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

Mit Pandas:

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 

ein wenig von @cᴏʟᴅsᴘᴇᴇᴅ auf Logik Diebstahl (Das ist viel klüger als die obige Lösung), aber unter Verwendung 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

Nur um zu bemerken, dass die BY-Anweisung in SAS Gruppen gemäß der Reihenfolge in der Datei verarbeitet und nur mit aufeinanderfolgenden Gruppen handelt (zB AAA BBB AAA ist 3 Gruppen, während 'df.groupby' diese 2 Gruppen berücksichtigt) ... Nicht, dass es hier wichtig ist, aber es ist nur erwähnenswert ... –

1

ich so das Gefühl ist natürlich ein groupby Konzept und idealerweise einen groupby basierten Ansatz verwenden würde, obwohl es sicherlich nichts falsch mit einem Shift-basierten Ansatz entweder (siehe die kurze Diskussion über diesen für mehr unten):

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

nth(0) wählt die erste Reihe jeder groupby und nth(-1) letzten mit nth([0,-1]) sowohl auswählt. Dann fehlen die anderen Zeilen, die einfach mit fillna(0) gefüllt werden können.

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 

In Bezug auf den Kommentar von @JonClements, beachten Sie, dass in einer Antwort groupby Ergebnisse mit unveränderlichen Reihenfolge sortieren die Verschiebung Ansatz während Verwendung hängt von der Sortierreihenfolge (von denen jeder je bevorzugt werden könnte auf die spezifischen Lage).

Verwandte Themen