Saya memiliki tabel DataFrame "besar" dengan indeks adalah kode negara (alpha-3) dan kolom adalah tahun (1900 hingga 2000) yang diimpor melalui pd.read_csv(...) [seperti yang saya pahami, ini sebenarnya adalah string jadi saya perlu untuk lulus sebagai '1945' misalnya].

Nilainya adalah 0,1,2,3. Saya perlu "menyebarkan" nilai-nilai ini hingga non-0 berikutnya untuk setiap baris.

  • contoh : 0 0 1 0 0 3 0 0 2 1
  • menjadi: 0 0 1 1 1 3 3 3 2 1

Saya mengerti bahwa saya tidak boleh menggunakan iterasi (implementasi saat ini adalah seperti ini, seperti yang Anda lihat, menggunakan 2 loop tidak optimal, saya kira saya bisa menghilangkannya dengan menggunakan apply(row) )

def spread_values(df):
    
    for idx in df.index:
    previous_v = 0
        for t_year in range(min_year, max_year):
            current_v = df.loc[idx, str(t_year)]
            if current_v == 0 and previous_v != 0:
                df.loc[idx, str(t_year)] = previous_v
            else:
                previous_v = current_v

Namun saya diberitahu bahwa saya harus menggunakan fungsi apply() , atau vektorisasi atau pemahaman daftar karena tidak optimal?

Namun fungsi apply, terlepas dari sumbunya, tidak memungkinkan untuk secara dinamis mendapatkan indeks/kolom (yang saya perlu memperbarui sel secara kondisional), dan saya pikir masalah inti saya tidak dapat membuat opsi vec atau daftar berfungsi adalah karena Saya tidak memiliki kumpulan terbatas nama kolom melainkan rentang yang luas (semua contoh yang saya lihat menggunakan beberapa kolom bernama...)

Apa solusi yang lebih optimal / lebih elegan di sini?

ATAU apakah DataFrames tidak cocok untuk data saya sama sekali? apa yang harus saya gunakan sebagai gantinya?

0
olliaroa 19 November 2020, 15:08

1 menjawab

Jawaban Terbaik

Anda dapat menggunakan df.replace(to_replace=0, method='ffil). Ini akan mengisi semua angka nol dalam kerangka data Anda (kecuali untuk angka nol yang muncul di awal kerangka data Anda) dengan nilai bukan nol sebelumnya per kolom.

Jika Anda ingin melakukannya rowwise sayangnya fungsi .replace() tidak menerima argumen axis. Tetapi Anda dapat transpose dataframe Anda, mengganti nol dan transpose lagi: df.T.replace(0, method='ffill').T

1
Rik Kraan 19 November 2020, 13:08