Saya memiliki kerangka data panda besar dengan banyak kolom (c1 ... c8) dan ~32 juta baris. Kerangka data sudah diurutkan berdasarkan c1. Saya ingin mengambil nilai kolom lain dari baris yang berbagi nilai c1 tertentu.

Sesuatu seperti

keys = big_df['c1'].unique()
red = np.zeros(len(keys))
for i, key in enumerate(keys):
    inds = (big_df['c1'] == key)
    v1 = np.array(big_df.loc[inds]['c2'])
    v2 = np.array(big_df.loc[inds]['c6'])
    red[i] = reduce_fun(v1,v2)

Namun ini ternyata sangat lambat saya pikir karena memeriksa seluruh kolom untuk kriteria yang cocok (meskipun mungkin hanya ada 10 baris dari 32 juta yang relevan). Karena big_df diurutkan berdasarkan c1 dan kuncinya hanyalah daftar semua c1 unik, apakah ada cara cepat untuk mendapatkan array merah[] (yaitu saya tahu baris pertama dengan kunci berikutnya adalah baris setelah baris terakhir dari kunci sebelumnya, saya tahu bahwa baris terakhir untuk kunci adalah baris terakhir yang cocok dengan kunci, karena semua baris berikutnya dijamin tidak cocok).

Terima kasih,

Ilya

Sunting: Saya tidak yakin metode order unique() apa yang dihasilkan, tetapi pada dasarnya saya ingin memiliki nilai reduce_fun() untuk setiap kunci dalam kunci (), saya tidak terlalu peduli urutannya (mungkin urutan termudah adalah urutannya c1 sudah diurutkan).

Sunting2: Saya sedikit merestrukturisasi kode. Pada dasarnya, apakah ada cara yang efisien untuk membangun inds. big_df['c1'] == kunci membutuhkan 75,8% dari total waktu dalam data saya, sementara membuat v1, v2 membutuhkan 21,6% menurut profiler baris.

2
Ilya 8 Agustus 2017, 04:58

2 jawaban

Jawaban Terbaik

Daripada daftar, saya memilih kamus untuk menyimpan nilai yang dikurangi yang dikunci pada setiap item di c1.

red = {key: reduce_func(frame['c2'].values, frame['c7'].values) 
       for key, frame in df.groupby('c1')}
6
Alexander 8 Agustus 2017, 02:21

Bagaimana dengan pernyataan groupby dalam pemahaman daftar? Ini harus sangat efisien mengingat DataFrame sudah diurutkan berdasarkan c1:

Edit: Lupa bahwa groupby mengembalikan sebuah tuple. Ups!

red = [reduce_fun(g['c2'].values, g['c6'].values) for i, g in big_df.groupby('c1', sort=False)]

Tampaknya berjalan cukup cepat bagi saya (~ 2 detik untuk 30 juta baris acak dan reduce_fun sepele).

2
PaSTE 8 Agustus 2017, 12:47