python - through - Wie man über Zeilen in einem DataFrame in Pandas iteriert?




pandas number of rows (8)

Ich habe einen DataFrames von Pandas:

import pandas as pd
inp = [{'c1':10, 'c2':100}, {'c1':11,'c2':110}, {'c1':12,'c2':120}]
df = pd.DataFrame(inp)
print df

Ausgabe:

   c1   c2
0  10  100
1  11  110
2  12  120

Jetzt möchte ich über die Zeilen des obigen Rahmens iterieren. Ich möchte für jede Zeile auf ihre Elemente (Werte in Zellen) mit dem Namen der Spalten zugreifen können. Ich möchte zum Beispiel so etwas haben:

for row in df.rows:
   print row['c1'], row['c2']

Ist es möglich, das in Pandas zu tun?

Ich habe ähnliche Fragen gefunden . Aber es gibt mir nicht die Antwort, die ich brauche. Zum Beispiel wird vorgeschlagen, dort zu verwenden:

for date, row in df.T.iteritems():

oder

for row in df.iterrows():

Aber ich verstehe nicht, was das Zeilenobjekt ist und wie ich damit arbeiten kann.


Benutze Ituppuples () . Es ist schneller als Iterrows () :

for row in df.itertuples():
    print "c1 :",row.c1,"c2 :",row.c2

IMHO, die einfachste Entscheidung

 for ind in df.index:
     print df['c1'][ind], df['c2'][ind]

Sie können auch df.apply() , um über Zeilen zu iterieren und auf mehrere Spalten für eine Funktion zuzugreifen.

DataFrame.apply()

def valuation_formula(x, y):
    return x * y * 0.5

df['price'] = df.apply(lambda row: valuation_formula(row['x'], row['y']), axis=1)

Sie können die Funktion df.iloc wie folgt verwenden:

for i in range(0, len(df)):
    print df.iloc[i]['c1'], df.iloc[i]['c2']

Sie können einen eigenen Iterator schreiben, der namedtuple implementiert

from collections import namedtuple

def myiter(d, cols=None):
    if cols is None:
        v = d.values.tolist()
        cols = d.columns.values.tolist()
    else:
        j = [d.columns.get_loc(c) for c in cols]
        v = d.values[:, j].tolist()

    n = namedtuple('MyTuple', cols)

    for line in iter(v):
        yield n(*line)

Dies ist direkt vergleichbar mit pd.DataFrame.itertuples . Ich ziele darauf ab, die gleiche Aufgabe mit mehr Effizienz zu erfüllen.

Für den gegebenen Datenrahmen mit meiner Funktion:

list(myiter(df))

[MyTuple(c1=10, c2=100), MyTuple(c1=11, c2=110), MyTuple(c1=12, c2=120)]

Oder mit pd.DataFrame.itertuples :

list(df.itertuples(index=False))

[Pandas(c1=10, c2=100), Pandas(c1=11, c2=110), Pandas(c1=12, c2=120)]

Ein umfassender Test
Wir testen, ob alle Spalten verfügbar sind und die Spalten untergliedert sind.

def iterfullA(d):
    return list(myiter(d))

def iterfullB(d):
    return list(d.itertuples(index=False))

def itersubA(d):
    return list(myiter(d, ['col3', 'col4', 'col5', 'col6', 'col7']))

def itersubB(d):
    return list(d[['col3', 'col4', 'col5', 'col6', 'col7']].itertuples(index=False))

res = pd.DataFrame(
    index=[10, 30, 100, 300, 1000, 3000, 10000, 30000],
    columns='iterfullA iterfullB itersubA itersubB'.split(),
    dtype=float
)

for i in res.index:
    d = pd.DataFrame(np.random.randint(10, size=(i, 10))).add_prefix('col')
    for j in res.columns:
        stmt = '{}(d)'.format(j)
        setp = 'from __main__ import d, {}'.format(j)
        res.at[i, j] = timeit(stmt, setp, number=100)

res.groupby(res.columns.str[4:-1], axis=1).plot(loglog=True);


Um alle Zeilen in einem dataframe , können Sie dataframe verwenden:

for x in range(len(date_example.index)):
    print date_example['Date'].iloc[x]

Um die Zeile von DataFrame in Pandas zu durchlaufen, kann man verwenden:

itertuples() soll schneller sein als iterrows()

Aber sei vorsichtig, nach den Dokumenten (Pandas 0.21.1 im Moment):

  • Iterrows: dtype möglicherweise nicht von Zeile zu Zeile überein

    Da Iterrows für jede Zeile eine Reihe zurückgibt, werden in den Zeilen keine Dypen beibehalten (Dptypen werden für DataFrames übergreifend beibehalten).

  • Iterrows: Ändern Sie keine Zeilen

    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 Auswirkungen.

    Verwenden DataFrame.apply() stattdessen DataFrame.apply() :

    new_df = df.apply(lambda x: x * 2)
    
  • iptuples:

    Die Spaltennamen werden in Positionsnamen umbenannt, wenn sie ungültige Python-IDs sind, wiederholt werden oder mit einem Unterstrich beginnen. Bei einer großen Anzahl von Spalten (> 255) werden reguläre Tupel zurückgegeben.


Während iterrows() eine gute Option ist, kann itertuples() manchmal viel schneller sein:

df = pd.DataFrame({'a': randn(1000), 'b': randn(1000),'N': randint(100, 1000, (1000)), 'x': 'x'})

%timeit [row.a * 2 for idx, row in df.iterrows()]
# => 10 loops, best of 3: 50.3 ms per loop

%timeit [row[1] * 2 for row in df.itertuples()]
# => 1000 loops, best of 3: 541 µs per loop






dataframe