Gunakan indeks df1 asli untuk membuat seri:
df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)
Edit 2015
Beberapa melaporkan mendapatkan SettingWithCopyWarning
dengan kode ini.
Namun, kode masih berjalan dengan sempurna dengan versi panda saat ini 0.16.1.
>>> sLength = len(df1['a'])
>>> df1
a b c d
6 -0.269221 -0.026476 0.997517 1.294385
8 0.917438 0.847941 0.034235 -0.448948
>>> df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
a b c d e
6 -0.269221 -0.026476 0.997517 1.294385 1.757167
8 0.917438 0.847941 0.034235 -0.448948 2.228131
>>> p.version.short_version
'0.16.1'
The SettingWithCopyWarning
bertujuan untuk menginformasikan tugas mungkin tidak valid pada salinan Dataframe. Itu tidak selalu mengatakan Anda melakukan kesalahan (itu dapat memicu positif palsu) tetapi dari 0,13.0 itu memberi tahu Anda ada metode yang lebih memadai untuk tujuan yang sama. Kemudian, jika Anda mendapatkan peringatan, cukup ikuti sarannya : Coba gunakan .loc [row_index, col_indexer] = nilai sebagai gantinya
>>> df1.loc[:,'f'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
a b c d e f
6 -0.269221 -0.026476 0.997517 1.294385 1.757167 -0.050927
8 0.917438 0.847941 0.034235 -0.448948 2.228131 0.006109
>>>
Sebenarnya, ini adalah metode yang lebih efisien seperti yang dijelaskan dalam panda docs
Edit 2017
Seperti yang ditunjukkan dalam komentar dan oleh @Alexander, saat ini metode terbaik untuk menambahkan nilai-nilai Seri sebagai kolom baru dari DataFrame bisa menggunakan assign
:
df1 = df1.assign(e=pd.Series(np.random.randn(sLength)).values)
SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_index,col_indexer] = value instead
kwargs
kamus, seperti:df1 = df1.assign(**{'e': p.Series(np.random.randn(sLength)).values})
Ini adalah cara sederhana untuk menambahkan kolom baru:
df['e'] = e
sumber
e
(Series(np.random.randn(sLength))
) menghasilkan Seri 0-n yang diindeks. Jika Anda menetapkan ini ke df1 maka Anda mendapatkan beberapa sel NaN.my_dataframe = pd.DataFrame(columns=('foo', 'bar'))
. Mengembalikan suntingan AndaSaya berasumsi bahwa nilai indeks
e
cocok dengan yang ada didf1
.Cara termudah untuk memulai kolom baru bernama
e
, dan berikan nilai dari seri Andae
:assign (Pandas 0.16.0+)
Pada Pandas 0.16.0, Anda juga dapat menggunakan
assign
, yang menetapkan kolom baru ke DataFrame dan mengembalikan objek baru (salinan) dengan semua kolom asli selain yang baru.Seperti contoh ini (yang juga menyertakan kode sumber
assign
fungsi), Anda juga dapat menyertakan lebih dari satu kolom:Dalam konteks dengan contoh Anda:
Deskripsi fitur baru ini ketika pertama kali diperkenalkan dapat ditemukan di sini .
sumber
df['e'] = e.values
) tidak membuat salinan kerangka data, sedangkan opsi kedua (menggunakandf.assign
) tidak? Dalam kasus banyak kolom baru yang ditambahkan secara berurutan dan kerangka data yang besar saya berharap kinerja yang jauh lebih baik dari metode pertama.assign
adalah ketika menyatukan operasi Anda.df.assign(**df.mean().add_prefix('mean_'))
df_new = pd.concat([df1, df2], axis=1)
, mencatatnyaignore_index=False
secara default.Tampaknya dalam versi Panda terbaru cara untuk pergi adalah dengan menggunakan df.assign :
df1 = df1.assign(e=np.random.randn(sLength))
Itu tidak menghasilkan
SettingWithCopyWarning
.sumber
Melakukan ini secara langsung melalui NumPy akan menjadi yang paling efisien:
Perhatikan saran asli saya (sangat lama) adalah untuk menggunakan
map
(yang jauh lebih lambat):sumber
.map
untuk menggunakan seri yang ada, bukanlambda
? Saya mencobadf1['e'] = df1['a'].map(lambda x: e)
ataudf1['e'] = df1['a'].map(e)
tetapi bukan itu yang saya butuhkan. (Saya baru mengenal pyhon dan jawaban Anda sebelumnya sudah membantu saya)e
Seri maka Anda tidak perlu menggunakanmap
, gunakandf['e']=e
(@joaquins jawab).Penugasan kolom super sederhana
Rangka data panda diimplementasikan sebagai dict kolom yang dipesan.
Ini berarti bahwa
__getitem__
[]
tidak hanya dapat digunakan untuk mendapatkan kolom tertentu, tetapi__setitem__
[] =
dapat digunakan untuk menetapkan kolom baru.Misalnya, kerangka data ini dapat memiliki kolom yang ditambahkan padanya hanya dengan menggunakan
[]
accessorPerhatikan bahwa ini berfungsi bahkan jika indeks bingkai data tidak aktif.
[] = adalah cara untuk pergi, tapi hati-hati!
Namun, jika Anda memiliki
pd.Series
dan mencoba untuk menetapkannya ke kerangka data di mana indeks tidak aktif, Anda akan mengalami masalah. Lihat contoh:Ini karena secara
pd.Series
default memiliki indeks yang dihitung dari 0 hingga n. Dan[] =
metode panda mencoba menjadi "pintar"Apa yang sebenarnya terjadi.
Ketika Anda menggunakan
[] =
metode panda diam-diam melakukan gabungan luar atau gabungan luar menggunakan indeks kerangka data tangan kiri dan indeks seri tangan kanan.df['column'] = series
Catatan samping
Ini dengan cepat menyebabkan disonansi kognitif, karena
[]=
metode ini mencoba melakukan banyak hal berbeda tergantung pada input, dan hasilnya tidak dapat diprediksi kecuali Anda hanya tahu cara kerja panda. Karena itu saya akan menyarankan terhadap[]=
basis kode, tetapi ketika mengeksplorasi data dalam notebook, itu baik-baik saja.Mengatasi masalah
Jika Anda memiliki
pd.Series
dan menginginkannya ditetapkan dari atas ke bawah, atau jika Anda mengkode kode produktif dan Anda tidak yakin dengan urutan indeks, Anda layak untuk melindungi untuk masalah seperti ini.Anda bisa downcast
pd.Series
kenp.ndarray
ataulist
, ini akan melakukan trik.atau
Tetapi ini tidak terlalu eksplisit.
Beberapa coder mungkin datang dan berkata "Hei, ini terlihat berlebihan, saya hanya akan mengoptimalkan ini saja".
Cara eksplisit
Pengaturan indeks
pd.Series
menjadi indeksdf
eksplisit.Atau lebih realistis, Anda mungkin sudah memiliki
pd.Series
.Sekarang bisa ditugaskan
Cara alternatif dengan
df.reset_index()
Karena disonansi indeks adalah masalahnya, jika Anda merasa bahwa indeks dari kerangka data tidak boleh menentukan hal-hal, Anda dapat dengan mudah menjatuhkan indeks, ini harus lebih cepat, tetapi itu tidak terlalu bersih, karena fungsi Anda sekarang mungkin melakukan dua hal.
Catatan aktif
df.assign
Sementara
df.assign
membuatnya lebih eksplisit apa yang Anda lakukan, sebenarnya memiliki semua masalah yang sama seperti di atas[]=
Berhati-hatilah dengan
df.assign
kolom Anda yang tidak dipanggilself
. Itu akan menyebabkan kesalahan. Ini membuatdf.assign
bau , karena ada jenis artefak dalam fungsinya.Anda mungkin berkata, "Baiklah, saya tidak akan menggunakannya
self
". Tapi siapa yang tahu bagaimana fungsi ini berubah di masa depan untuk mendukung argumen baru. Mungkin nama kolom Anda akan menjadi argumen dalam pembaruan panda baru, yang menyebabkan masalah dengan peningkatan.sumber
[] =
metode, Panda diam-diam melakukan gabungan luar atau gabungan luar ". Ini adalah informasi yang paling penting dalam keseluruhan topik. Tetapi bisakah Anda memberikan tautan ke dokumentasi resmi tentang cara[]=
kerja operator?Cara termudah: -
Dengan cara ini Anda menghindari apa yang disebut pengindeksan berantai saat menetapkan nilai baru dalam objek panda. Klik di sini untuk membaca lebih lanjut .
sumber
Jika Anda ingin mengatur seluruh kolom baru ke nilai dasar awal (mis.
None
), Anda bisa melakukan ini:df1['e'] = None
Ini sebenarnya akan menetapkan tipe "objek" ke sel. Jadi nanti Anda bebas memasukkan tipe data yang kompleks, seperti daftar, ke dalam sel individual.
sumber
Saya mendapatkan yang ditakuti
SettingWithCopyWarning
, dan itu tidak diperbaiki dengan menggunakan sintaks iloc. DataFrame saya dibuat oleh read_sql dari sumber ODBC. Menggunakan saran dari lowtech di atas, yang berikut ini berfungsi untuk saya:Ini berfungsi dengan baik untuk menyisipkan kolom di akhir. Saya tidak tahu apakah ini yang paling efisien, tetapi saya tidak suka pesan peringatan. Saya pikir ada solusi yang lebih baik, tetapi saya tidak dapat menemukannya, dan saya pikir itu tergantung pada beberapa aspek indeks.
Catatan . Bahwa ini hanya berfungsi sekali dan akan memberikan pesan kesalahan jika mencoba menimpa dan kolom yang ada.
Catatan Seperti di atas dan dari 0.16.0 assign adalah solusi terbaik. Lihat dokumentasi http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.assign.html#pandas.DataFrame.assign Berfungsi dengan baik untuk tipe aliran data di mana Anda tidak menimpa nilai perantara Anda.
sumber
list_of_e
yang memiliki data yang relevan.df['e'] = list_of_e
sumber
tolist()
perintahnya mungkin membantu.Jika kolom yang Anda coba tambahkan adalah variabel seri maka cukup:
Ini berfungsi dengan baik bahkan jika Anda mengganti kolom yang ada. Cukup ketik new_columns_name sama dengan kolom yang ingin Anda ganti. Itu hanya akan menimpa data kolom yang ada dengan data seri baru.
sumber
Jika bingkai data dan objek Seri memiliki indeks yang sama ,
pandas.concat
juga berfungsi di sini:Jika mereka tidak memiliki indeks yang sama:
sumber
Sangat mudah:
Contoh:
sumber
Biarkan saya tambahkan saja, seperti untuk hum3 ,
.loc
tidak menyelesaikanSettingWithCopyWarning
dan saya harus menggunakandf.insert()
. Dalam kasus saya false positive dihasilkan oleh pengindeksan rantai "palsu"dict['a']['e']
, di mana'e'
kolom baru, dandict['a']
DataFrame berasal dari kamus.Perhatikan juga bahwa jika Anda tahu apa yang Anda lakukan, Anda dapat beralih dari peringatan menggunakan
pd.options.mode.chained_assignment = None
dan daripada menggunakan salah satu solusi lain yang diberikan di sini.sumber
untuk menyisipkan kolom baru di lokasi tertentu (0 <= loc <= jumlah kolom) dalam bingkai data, cukup gunakan Dataframe.insert:
Oleh karena itu, jika Anda ingin menambahkan kolom e di akhir bingkai data yang disebut df , Anda dapat menggunakan:
nilai dapat berupa Seri, bilangan bulat (dalam hal ini semua sel diisi dengan nilai yang satu ini), atau struktur mirip array
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.insert.html
sumber
Sebelum menetapkan kolom baru, jika Anda memiliki data yang diindeks, Anda perlu mengurutkan indeks. Setidaknya dalam kasus saya, saya harus:
sumber
Satu hal yang perlu diperhatikan, adalah jika Anda melakukannya
ini secara efektif akan menjadi join kiri di df1.index. Jadi jika Anda ingin memiliki efek gabungan luar , solusi saya yang mungkin tidak sempurna adalah membuat bingkai data dengan nilai indeks yang meliputi semesta data Anda, dan kemudian gunakan kode di atas. Sebagai contoh,
sumber
Saya sedang mencari cara umum untuk menambahkan kolom
numpy.nan
s ke dalam dataframe tanpa menjadi bodohSettingWithCopyWarning
.Dari berikut ini:
numpy
array NaNs in-lineSaya datang dengan ini:
sumber
Untuk menambahkan kolom baru, 'e', ke bingkai data yang ada
sumber
Demi kelengkapan - solusi lain menggunakan metode DataFrame.eval () :
Data:
Larutan:
sumber
Untuk membuat kolom kosong
sumber
Berikut ini adalah apa yang saya lakukan ... Tapi saya cukup baru untuk panda dan benar-benar Python secara umum, jadi tidak ada janji.
sumber
Jika Anda mendapatkan
SettingWithCopyWarning
, perbaikan yang mudah adalah menyalin DataFrame yang Anda coba tambahkan kolom.sumber