Saya memiliki DataFrame
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
Output:
c1 c2
0 10 100
1 11 110
2 12 120
Sekarang saya ingin iterate atas deretan frame ini. Untuk setiap baris saya ingin dapat mengakses elemen-elemen (nilai-nilai dalam sel) dengan nama kolom. Misalnya:
for row in df.rows:
print row['c1'], row['c2']
Adalah mungkin untuk melakukan itu di panda?
Saya menemukan ini pertanyaan serupa. Tapi itu tidak memberikan saya jawaban yang saya butuhkan. Misalnya, disarankan tidak menggunakan:
for date, row in df.T.iteritems():
atau
for row in df.iterrows():
Tapi aku tidak mengerti apa baris
objek dan bagaimana saya dapat bekerja dengan itu.
DataFrame.iterrows adalah generator yang menghasilkan kedua indeks dan baris
import pandas as pd
import numpy as np
df = pd.DataFrame([{'c1':10, 'c2':100}, {'c1':11,'c2':110}, {'c1':12,'c2':120}])
<!- ->
for index, row in df.iterrows():
print(row['c1'], row['c2'])
Output:
10 100
11 110
12 120
Pertama pertimbangkan jika anda benar-benar perlu untuk iterate lebih dari baris dalam DataFrame. Lihat jawaban untuk alternatif.
Jika anda masih perlu untuk iterate atas baris, anda dapat menggunakan metode berikut. Beberapa catatan penting peringatan yang tidak disebutkan dalam salah satu jawaban yang lain.
untuk index, baris di df.iterrows(): cetak row["1"], row["c2"]
untuk baris di df.itertuples(indeks=True, name='Panda'): cetak getattr(baris, "1"), getattr(baris, "c2")
itertuples()
seharusnya lebih cepat dari iterrows()
Tapi perlu diketahui, menurut dokumen (panda 0.24.2 pada saat ini):
dtype
mungkin tidak cocok dari baris ke barisKarena iterrows kembali Seri untuk masing-masing baris, itu tidak melestarikan dtypes seluruh baris (dtypes yang diawetkan di kolom untuk DataFrames). Untuk melestarikan dtypes sementara iterasi baris, itu adalah lebih baik untuk menggunakan itertuples() yang mengembalikan namedtuples dari nilai-nilai dan yang umumnya jauh lebih cepat dari iterrows()
Anda harus jangan pernah memodifikasi sesuatu yang anda iterasi. Ini tidak dijamin untuk bekerja pada semua kasus. Tergantung pada jenis data, iterator kembali salinan dan tidak melihat, dan menulis untuk itu tidak akan berpengaruh.
Gunakan DataFrame.apply() sebagai gantinya:
new_df = df.menerapkan(lambda x: x * 2)
nama-nama kolom yang akan diganti ke posisi nama jika mereka tidak valid Python pengenal, berulang, atau mulai dengan sebuah garis bawah. Dengan jumlah kolom (>255), biasa tupel dikembalikan.
Lihat panda docs pada iterasi untuk rincian lebih lanjut.
Bagaimana untuk iterate atas baris di DataFrame di Panda?
Jawaban: DON'T!
Iterasi di panda adalah aplikasi anti-pola, dan adalah sesuatu yang anda harus hanya ingin anda lakukan ketika anda telah kehabisan semua opsi yang mungkin. Anda tidak harus mempertimbangkan menggunakan fungsi apapun dengan "
iter
" dalam namanya untuk sesuatu yang lebih dari beberapa ribu baris atau anda akan memiliki untuk mendapatkan digunakan untuk banyak menunggu. Apakah anda ingin mencetak DataFrame? GunakanDataFrame.to_string()
. Apakah anda ingin menghitung sesuatu? Dalam kasus itu, pencarian untuk metode dalam urutan ini (daftar dimodifikasi dari di sini):
- Vektorisasi
- Acpi rutinitas
- Daftar Pemahaman (vanilla
untuk
loop)DataFrame.apply()
: i) Pengurangan yang dapat dilakukan di acpi, ii) Perulangan pada python ruangDataFrame.itertuples()
daniteritems()
DataFrame.iterrows()
iterrows
danitertuples
(baik menerima banyak suara di jawaban untuk pertanyaan ini) harus digunakan dalam keadaan yang sangat langka, seperti menghasilkan baris benda/nametuples untuk pemrosesan sekuensial, yang benar-benar satu-satunya hal fungsi-fungsi ini berguna untuk. Banding ke Otoritas Dokumen halaman pada iterasi memiliki besar merah kotak peringatan yang mengatakan: Iterasi melalui panda benda-benda yang umumnya lambat. Dalam banyak kasus, iterasi secara manual di atas baris yang tidak diperlukan [...].Lebih cepat dari Perulangan: Vektorisasi, Acpi
Baik jumlah operasi dasar dan perhitungan "vectorised" oleh panda (baik melalui NumPy, atau melalui Cythonized fungsi). Ini meliputi aritmatika, perbandingan, (kebanyakan) pengurangan, penyusunan kembali (seperti berputar), bergabung, dan groupby operasi. Melihat melalui dokumentasi pada Penting Dasar Functionality untuk menemukan cocok vectorised metode untuk masalah anda. Jika tidak ada, jangan ragu untuk menulis anda sendiri menggunakan custom acpi extensions.
Hal Terbaik berikutnya: Daftar Pemahaman
Daftar pemahaman yang harus anda berikutnya port of call jika 1) tidak ada vectorized solusi yang tersedia, 2) kinerja adalah penting, tetapi tidak cukup penting untuk pergi melalui kerumitan cythonizing kode anda, dan 3) anda're berusaha untuk melakukan elementwise transformasi pada kode anda. Ada baik jumlah bukti untuk menunjukkan bahwa daftar pemahaman yang cukup cepat (dan bahkan kadang-kadang lebih cepat) untuk banyak umum panda tugas. Rumus sederhana,
# iterating over one column - `f` is some function that processes your data
result = [f(x) for x in df['col']]
# iterating over two columns, use `zip`
result = [f(x, y) for x, y in zip(df['col1'], df['col2'])]
# iterating over multiple columns
result = [f(row[0], ..., row[n]) for row in df[['col1', ...,'coln']].values]
Let's menunjukkan perbedaan dengan contoh sederhana untuk menambahkan dua panda kolom B+
. Ini adalah vectorizable operaton, sehingga akan mudah untuk membandingkan kinerja dari metode yang dibahas di atas.
Benchmarking kode, untuk referensi anda.
Saya harus menyebutkan, bagaimanapun, bahwa itu isn't selalu dipotong dan kering. Kadang-kadang jawaban "yang merupakan metode terbaik untuk operasi" adalah "itu tergantung pada data anda". Saran saya adalah untuk menguji pendekatan yang berbeda pada data anda sebelum menetap di satu.
apply
lambat (tapi sekarang lambat sebagai iter*
keluarga. Ada, bagaimanapun, situasi di mana satu dapat (atau harus) mempertimbangkan terapkan
sebagai serangkaian alternatif, terutama di beberapa GroupBy
operasi).
* Panda string metode "vectorized" dalam arti bahwa mereka ditentukan pada seri tetapi beroperasi pada masing-masing elemen. Mekanisme yang mendasari masih berulang, karena operasi string secara inheren sulit untuk vectorize.Anda harus menggunakan df.iterrows()
. Meskipun iterasi baris-demi-baris ini tidak efisien terutama sejak Seri benda yang akan dibuat.
Sementara iterrows()
adalah pilihan yang baik, kadang-kadang itertuples()
dapat menjadi 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
Anda juga dapat menggunakan df.berlaku()
untuk iterate atas baris dan beberapa kolom untuk fungsi.
def valuation_formula(x, y):
return x * y * 0.5
df['price'] = df.apply(lambda row: valuation_formula(row['x'], row['y']), axis=1)
Anda dapat menulis sendiri iterator yang menerapkan 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)
Hal ini secara langsung sebanding dengan pd.DataFrame.itertuples
. I'm yang bertujuan untuk melakukan tugas yang sama dengan efisiensi yang lebih.
Untuk diberikan dataframe dengan fungsi:
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)]
Komprehensif tes Kami menguji semua kolom yang tersedia dan pembagian 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);
Kadang-kadang berguna pola adalah:
# Borrowing @KutalmisB df example
df = pd.DataFrame({'col1': [1, 2], 'col2': [0.1, 0.2]}, index=['a', 'b'])
# The to_dict call results in a list of dicts
# where each row_dict is a dictionary with k:v pairs of columns:value for that row
for row_dict in df.to_dict(orient='records'):
print(row_dict)
Yang menghasilkan:
{'col1':1.0, 'col2':0.1}
{'col1':2.0, 'col2':0.2}
Loop semua baris dalam dataframe
dan gunakan ** nilai-nilai dari setiap baris ketika**, namedtuples
dapat dikonversi ke `ndarray ini. Misalnya:
df = pd.DataFrame({'col1': [1, 2], 'col2': [0.1, 0.2]}, index=['a', 'b'])
Iterasi baris:
for row in df.itertuples(index=False, name='Pandas'):
print np.asarray(row)
hasil:
[ 1. 0.1]
[ 2. 0.2]
Harap dicatat bahwa jika index=True
, indeks ditambahkan sebagai elemen pertama dari tuple, yang mungkin tidak diinginkan untuk beberapa aplikasi.
Untuk melihat dan memodifikasi nilai-nilai, saya akan menggunakan iterrows()
. Dalam loop for dan dengan menggunakan tupel membongkar (lihat contoh: saya, baris
), saya gunakan baris
untuk hanya melihat nilai dan menggunakan saya
dengan loc
metode ketika saya ingin mengubah nilai-nilai. Seperti yang tercantum dalam jawaban sebelumnya, di sini anda tidak harus mengubah sesuatu yang anda iterasi.
bagi saya, baris di df.iterrows(): jika row['A'] == 'Old_Value': df.loc[i,'A'] = 'New_value'
Di sini baris
di loop adalah salinan dari baris itu, dan tidak melihat itu. Oleh karena itu, anda TIDAK harus menulis sesuatu seperti row['A'] = 'New_Value'
, itu tidak akan mengubah DataFrame. Namun, anda dapat menggunakan aku
dan loc
dan menentukan DataFrame untuk melakukan pekerjaan.
Ada cara untuk iterate membuang baris sementara mendapatkan DataFrame kembali, dan bukan Seri. Saya don't melihat siapa pun menyebutkan bahwa anda dapat melewati indeks sebagai daftar untuk baris yang dikembalikan sebagai DataFrame:
for i in range(len(df)):
row = df.iloc[[i]]
Catatan penggunaan kurung ganda. Ini kembali DataFrame dengan satu baris.
Anda juga dapat melakukan numpy
pengindeksan untuk kecepatan yang lebih besar up. It's tidak benar-benar iterasi tapi bekerja jauh lebih baik daripada iterasi untuk aplikasi tertentu.
subset = row['c1'][0:5]
all = row['c1'][:]
Anda juga mungkin ingin melemparkannya ke sebuah array. Indeks ini/seleksi seharusnya bertindak seperti Numpy array sudah tapi aku berlari ke dalam masalah dan dibutuhkan untuk cor
np.asarray(all)
imgs[:] = cv2.resize(imgs[:], (224,224) ) #resize every image in an hdf5 file
Ada begitu banyak cara untuk iterate atas baris di panda dataframe. Salah satu yang sangat sederhana dan intuitif adalah :
df=pd.DataFrame({'A':[1,2,3], 'B':[4,5,6],'C':[7,8,9]})
print(df)
for i in range(df.shape[0]):
# For printing the second column
print(df.iloc[i,1])
# For printing more than one columns
print(df.iloc[i,[0,2]])
Contoh ini menggunakan iloc untuk mengisolasi masing-masing digit pada data frame.
import pandas as pd
a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
mjr = pd.DataFrame({'a':a, 'b':b})
size = mjr.shape
for i in range(size[0]):
for j in range(size[1]):
print(mjr.iloc[i, j])