Ich versuche, die Anzahl der Zeilen zu zählen, die erforderlich sind, damit ein bestimmter Zeilenwert 'Neg' von seiner Standardeinstellung 1 zu 1 wird, und erhalte diese Anzahl, wo immer Neg = 1 ist, in einer neuen Spalte namens 'dsf'. Ich habe das folgende Code-Snippet ausprobiert. Ich bin mir nicht sicher, warum, aber dies setzt 0 für alle 'dsf'-Werte.

Warum ist das falsch?

/Code

full_data['dsf'] = 0
counter = 0
for i,r in full_data.iterrows():
    if r['neg'] == 0:
        counter+=1
        r['dsf'] = 0
    else:
        r['dsf'] = counter
        counter = 0
full_data

Aktueller Output:

    datehour            pft     rev         mgn        neg  dsf
0   2018-04-01 00:00:00 53.1783 110.8514    0.479726    0   0
1   2018-04-01 00:30:00 51.1496 105.9060    0.482972    0   0
2   2018-04-01 01:00:00 42.9360 120.7555    0.355561    1   0
3   2018-04-01 01:30:00 37.8455 114.5514    0.330380    0   0
4   2018-04-01 02:00:00 43.9254 99.1340     0.443091    1   0

Ideale Leistung:

    datehour            pft     rev         mgn         neg dsf
0   2018-04-01 00:00:00 53.1783 110.8514    0.479726    0   0
1   2018-04-01 00:30:00 51.1496 105.9060    0.482972    0   0
2   2018-04-01 01:00:00 42.9360 120.7555    0.355561    1   3
3   2018-04-01 01:30:00 37.8455 114.5514    0.330380    0   0
4   2018-04-01 02:00:00 43.9254 99.1340     0.443091    1   2
1
Deepak 19 Apr. 2018 im 12:53

3 Antworten

Beste Antwort

Dies ist nur eine andere Lösung für Ihr Problem, die im Vergleich zur Verwendung von Iterrows viel schneller sein sollte. Sie sollten immer versuchen, mit Pandas so viel Vektorisierung wie möglich zu verwenden.

df = pd.DataFrame({'neg': [0,0,1, 0, 1,0, 0, 1]})
indexes = df[df['neg'] == 1].index
shifted = indexes + 1
values = indexes - indexes.to_series().shift().fillna(0)
df.assign(dfs=pd.Series(vals, index=indexes)).fillna(0)

    neg dfs
0   0   0.0
1   0   0.0
2   1   3.0
3   0   0.0
4   1   2.0
5   0   0.0
6   0   0.0
7   1   3.0

Wenn Sie möchten, können Sie die dfs-Spalte selbst in int konvertieren

0
Quickbeam2k1 19 Apr. 2018 im 11:53

Sie sollten counter außerhalb der for-Schleife initialisieren. Hier ist ein Beispiel:

df = pd.DataFrame({'neg': [0, 0, 1, 0, 1]}) 

df['dsf'] = 0
counter  = 1

for i, j in df.iterrows():
 if j['neg'] == 0:
  j['dsf'] = 0
  counter += 1
else:
  j['dsf'] = counter
  counter = 1

df  

Ausgabe:

   neg dsf
0   0   0
1   0   0
2   1   3
3   0   0
4   1   2

Beachten Sie, dass das Ergebnis genau dem gewünschten Ergebnis entspricht. Wenn Sie jedoch nur die Nullwerte zählen möchten, sollten Sie die Zählung außerhalb und am Ende der for-Schleife mit 0 initialisieren. Und das Ergebnis sollte so aussehen:

neg dsf
0   0   0
1   0   0
2   1   2
3   0   0
4   1   1
1
cnicollet 19 Apr. 2018 im 10:32

Von iterrows docs:

Sie sollten niemals etwas ändern, über das Sie iterieren. Dies funktioniert nicht garantiert in allen Fällen. Abhängig von den Datentypen gibt der Iterator eine Kopie und keine Ansicht zurück, und das Schreiben darauf hat keine Auswirkung.

In Ihrem Fall ändern Sie also in der for - Schleife nicht das Original DataFrame, da iterrows eine Kopie zurückgibt. Weitere Informationen zu Ansichten und Kopien finden Sie unter http: //pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

Hier ist eine feste Version Ihres Codes:

df = pd.DataFrame([
    ['2018-04-01 00:00:00', 53.1783, 110.8514, 0.479726, 0], 
    ['2018-04-01 00:30:00', 51.1496, 105.9060, 0.482972, 0], 
    ['2018-04-01 01:00:00', 42.9360, 120.7555, 0.355561, 1], 
    ['2018-04-01 01:30:00', 37.8455, 114.5514, 0.330380, 0], 
    ['2018-04-01 02:00:00', 43.9254, 99.1340,  0.443091, 1]], 
    columns=['datehour', 'pft', 'rev', 'mgn', 'neg'])

df['dsf'] = 0
counter = 0

for i,r in df.iterrows():
    counter += 1
    if r['neg'] != 0:
        df.loc[i, 'dsf'] = counter
        counter = 0

print(df)
#                datehour     pft      rev         mgn   neg      dsf
# 0   2018-04-01 00:00:00 53.1783 110.8514    0.479726    0         0
# 1   2018-04-01 00:30:00 51.1496 105.9060    0.482972    0         0
# 2   2018-04-01 01:00:00 42.9360 120.7555    0.355561    1         3
# 3   2018-04-01 01:30:00 37.8455 114.5514    0.330380    0         0
# 4   2018-04-01 02:00:00 43.9254 99.1340     0.443091    1         2
0
Grigoriy Mikhalkin 19 Apr. 2018 im 10:55