Tambahkan kolom di dataframe dari daftar


95

Saya memiliki kerangka data dengan beberapa kolom seperti ini:

A   B   C  
0   
4
5
6
7
7
6
5

The kemungkinan rentang nilai A hanya 0-7 .

Juga, saya memiliki daftar 8 elemen seperti ini:

List=[2,5,6,8,12,16,26,32]  //There are only 8 elements in this list

Jika elemen di kolom A adalah n , saya perlu memasukkan elemen ke- n dari List di kolom baru, katakan 'D'.

Bagaimana saya bisa melakukan ini sekaligus tanpa mengulang seluruh kerangka data?

Dataframe yang dihasilkan akan terlihat seperti ini:

A   B   C   D
0           2
4           12
5           16
6           26
7           32
7           32
6           26
5           16

Catatan: Dataframe sangat besar dan iterasi adalah opsi opsi terakhir. Tetapi saya juga dapat mengatur elemen dalam 'Daftar' dalam struktur data lain seperti dict jika perlu.


1
Saya pikir Anda membutuhkan contoh mainan (lebih kecil), dengan hasil yang diinginkan. Kedengarannya atm agak kabur.
Andy Hayden

11
Jangan pernah memanggil variabel "Daftar". Dalam bahasa apapun.
lucid_dreamer

Jawaban:


51

IIUC, jika Anda membuat (sayangnya dinamai) Listmenjadi ndarray, Anda dapat mengindeksnya secara alami.

>>> import numpy as np
>>> m = np.arange(16)*10
>>> m[df.A]
array([  0,  40,  50,  60, 150, 150, 140, 130])
>>> df["D"] = m[df.A]
>>> df
    A   B   C    D
0   0 NaN NaN    0
1   4 NaN NaN   40
2   5 NaN NaN   50
3   6 NaN NaN   60
4  15 NaN NaN  150
5  15 NaN NaN  150
6  14 NaN NaN  140
7  13 NaN NaN  130

Di sini saya membangun yang baru m, tetapi jika Anda menggunakan m = np.asarray(List), hal yang sama harus bekerja: nilai-nilai df.Aakan memilih elemen yang sesuai m.


Perhatikan bahwa jika Anda menggunakan versi lama numpy, Anda mungkin harus menggunakannya m[df.A.values]- di masa lalu, numpytidak cocok dengan yang lain, dan beberapa pemfaktoran ulang pandasmenyebabkan beberapa sakit kepala. Banyak hal telah membaik sekarang.


Hai @SM. Saya mengerti apa yang Anda katakan tetapi saya mendapatkan kesalahan ini: Traceback (most recent call last): File "./b.py", line 24, in <module> d["D"] = m[d.A] IndexError: unsupported iterator index
surai

1
@mane: urf, itu numpybug lama . Apakah d["D"] = m[d.A.values]bekerja untuk Anda?
DSM

278

Cukup tetapkan daftar secara langsung:

df['new_col'] = mylist

Alternatif
Mengonversi daftar menjadi seri atau larik dan kemudian menetapkan:

se = pd.Series(mylist)
df['new_col'] = se.values

atau

df['new_col'] = np.array(mylist)

3
pykernel_launcher.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy """Entry point for launching an IPython kernel.
Ilya Rusin

@ Sparrow akan menggunakan pd.Seriesefek dtype? Maksud saya, apakah itu akan meninggalkan float sebagai float dan string sebagai string? Atau akankah elemen dalam daftar default ke string?
3kstc

2
@IlyaRusin, false positive yang bisa diabaikan dalam kasus ini. Untuk info lebih lanjut: stackoverflow.com/questions/20625582/…
sparrow

1
Ini dapat disederhanakan menjadi: df ['new_col'] = pd.Series (mylist) .values
smartse

16

Solusi untuk menyempurnakan yang terbaik dari @sparrow.

Biarkan df , jadilah kumpulan data Anda, dan buat daftar saya dengan nilai yang ingin Anda tambahkan ke kerangka data.

Misalkan Anda ingin memanggil kolom baru Anda dengan sederhana, kolom_baru

Pertama buat daftarnya menjadi Seri:

column_values = pd.Series(mylist)

Kemudian gunakan fungsi sisipkan untuk menambahkan kolom. Fungsi ini memiliki keuntungan untuk memungkinkan Anda memilih di posisi mana Anda ingin meletakkan kolom. Pada contoh berikut kita akan memposisikan kolom baru di posisi pertama dari kiri (dengan mengatur loc = 0)

df.insert(loc=0, column='new_column', value=column_values)

Ini tidak akan berfungsi jika Anda mengubah indeks df Anda menjadi sesuatu selain 1,2,3 ... dalam hal ini Anda harus menambahkan yang tersirat: column_values.index = df.index
Guy s

8

Pertama mari kita buat kerangka data yang Anda miliki, saya akan mengabaikan kolom B dan C karena tidak relevan.

df = pd.DataFrame({'A': [0, 4, 5, 6, 7, 7, 6,5]})

Dan pemetaan yang Anda inginkan:

mapping = dict(enumerate([2,5,6,8,12,16,26,32]))

df['D'] = df['A'].map(mapping)

Selesai!

print df

Keluaran:

   A   D
0  0   2
1  4  12
2  5  16
3  6  26
4  7  32
5  7  32
6  6  26
7  5  16

1
Saya pikir OP sudah tahu bagaimana melakukan ini. Dengan membaca saya, masalahnya adalah membangun Ddari elemen Adan List("Jika elemen dalam kolom A adalah n, saya perlu memasukkan elemen ke n dari Daftar di kolom baru, katakan 'D'.")
DSM

SO telah berubah menjadi semacam F (* & status pengasuh. Terima kasih kepada @DSM untuk komentarnya tetapi saya tidak dapat memperbaiki posting sampai itu ditinjau oleh sejawat. Dan kemudian ditolak karena terlalu cepat. Dan kemudian saya dapat melakukan peer review hasil edit saya sendiri. dan kemudian terlambat karena jawaban (IMHO) yang lebih buruk adalah "diterima". JADI benar-benar mendapat beberapa meta-nanny yang kurang membantu !!!!
Phil Cooper

Yah, saya tidak dapat berbicara mewakili para pengasuh, tetapi Anda akan menemukan bahwa pendekatan Anda adalah tentang urutan besarnya lebih lambat pada array panjang. Dalam hal lain, tentu saja, memilih antara np.array(List)[df.A]dan df["A"].map(dict(enumerate(List)))sebagian besar adalah masalah preferensi.
DSM

Hai Phil, saya hanya melihat solusi Anda dan komentar DSM dan tidak pernah kembali lagi karena solusi DSM berfungsi dengan baik untuk saya. Tapi sekarang melihat solusi Anda, itu juga berhasil. Saya telah menjalankan solusi DSM pada kumpulan data saya sekitar 200k entri dan berjalan dalam beberapa detik dengan semua perhitungan lain yang saya miliki. Saya benar-benar baru mengenal python-pandas dan secara pribadi tidak mencari sesuatu yang elegan atau hebat; apa pun yang berhasil baik-baik saja. Tapi jujur, terima kasih atas solusinya.
surai

2

Pertanyaan lama; tetapi saya selalu mencoba menggunakan kode tercepat!

Saya memiliki daftar besar dengan 69 juta uint64. np.array () adalah yang tercepat untuk saya.

df['hashes'] = hashes
Time spent: 17.034842014312744

df['hashes'] = pd.Series(hashes).values
Time spent: 17.141014337539673

df['key'] = np.array(hashes)
Time spent: 10.724546194076538
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.