Pertanyaan Bagaimana mengulang baris dalam DataFrame di Pandas?


Saya memiliki DataFrames dari panda:

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

Keluaran:

   c1   c2
0  10  100
1  11  110
2  12  120

Sekarang saya ingin mengulang di atas deretan bingkai di atas. Untuk setiap baris saya ingin dapat mengakses elemen-elemennya (nilai dalam sel) dengan nama kolom. Jadi, misalnya, saya ingin memiliki sesuatu seperti itu:

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

Mungkinkah melakukan itu di panda?

saya menemukan pertanyaan serupa. Tapi itu tidak memberi saya jawaban yang saya butuhkan. Misalnya, disarankan di sana untuk menggunakan:

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

atau

for row in df.iterrows():

Tapi saya tidak mengerti apa itu row objek dan bagaimana saya bisa bekerja dengannya.


758
2018-05-10 07:04


asal


Jawaban:


iterrows adalah generator yang menghasilkan indeks dan baris

In [18]: for index, row in df.iterrows():
   ....:     print row['c1'], row['c2']
   ....:     
10 100
11 110
12 120

1092
2018-05-10 07:07



Untuk iterasi melalui baris DataFrame di panda yang dapat digunakan:

itertuples() seharusnya lebih cepat dari iterrows()

Namun perlu disadari, menurut dokumen (panda 0,21.1 saat ini):

  • iterrows: dtype mungkin tidak cocok dari baris ke baris

    Karena iterrows mengembalikan Seri untuk setiap baris, itu tidak dipertahankan dtypes di baris (dtypes diawetkan di seluruh kolom untuk DataFrames).

  • iterrows: Jangan modifikasi baris

    Kamu harus jangan pernah memodifikasi sesuatu yang Anda iterasi. Ini tidak dijamin bekerja dalam semua kasus. Bergantung pada tipe data, iterator mengembalikan salinan dan bukan tampilan, dan menulisnya tidak akan berpengaruh.

    Menggunakan DataFrame.apply () sebagai gantinya:

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

    Nama kolom akan diubah namanya menjadi nama posisi jika mereka adalah pengidentifikasi Python yang tidak valid, diulang, atau dimulai dengan garis bawah. Dengan sejumlah besar kolom (> 255), tupel biasa dikembalikan.


140
2017-12-07 16:41



Sementara iterrows() adalah pilihan yang bagus, terkadang itertuples() bisa jauh lebih cepat:

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

115
2017-09-20 13:52



Anda juga bisa menggunakan df.apply() untuk mengulang baris dan mengakses beberapa kolom untuk suatu fungsi.

dokumen: 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)

61
2018-06-01 06:24



Anda dapat menggunakan fungsi df.iloc sebagai berikut:

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

42
2017-09-07 12:56



Menggunakan itertuples (). Lebih cepat dari iterrows ():

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

13
2017-07-27 16:32



aku sedang mencari Cara melakukan iterasi pada baris DAN kolom dan berakhir di sini jadi:

for i, row in df.iterrows():
    for j, column in row.iteritems():
        print(column)

11
2018-01-17 09:41



Untuk mengulang semua baris dalam a dataframe Kamu dapat memakai:

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

10
2018-03-11 22:44



Anda dapat menulis iterator Anda sendiri yang diimplementasikan namedtuple

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)

Ini langsung sebanding dengan pd.DataFrame.itertuples. Saya bertujuan melakukan tugas yang sama dengan lebih efisien.


Untuk dataframe yang diberikan dengan fungsi saya:

list(myiter(df))

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

Atau dengan pd.DataFrame.itertuples:

list(df.itertuples(index=False))

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

Tes yang komprehensif
Kami menguji membuat semua kolom tersedia dan menyematkan kolom.

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);

enter image description here

enter image description here


10
2017-11-07 04:15



IMHO, keputusan paling sederhana

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

6
2017-11-02 10:33