Menambahkan kolom baru ke DataFrame yang ada di Python panda

979

Saya memiliki DataFrame yang diindeks berikut dengan kolom dan baris bernama tidak- nomor terus menerus:

          a         b         c         d
2  0.671399  0.101208 -0.181532  0.241273
3  0.446172 -0.243316  0.051767  1.577318
5  0.614758  0.075793 -0.451460 -0.012493

Saya ingin menambahkan kolom baru 'e',, ke bingkai data yang ada dan tidak ingin mengubah apa pun dalam bingkai data (yaitu, kolom baru selalu memiliki panjang yang sama dengan DataFrame).

0   -0.335485
1   -1.166658
2   -0.385571
dtype: float64

Bagaimana saya bisa menambahkan kolom eke contoh di atas?

tomasz74
sumber

Jawaban:

1043

Gunakan indeks df1 asli untuk membuat seri:

df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)

Edit 2015
Beberapa melaporkan mendapatkan SettingWithCopyWarningdengan 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 SettingWithCopyWarningbertujuan 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)
joaquin
sumber
24
jika Anda perlu menambahkan kolom menggunakan DataFrame.insert: df1.insert (0, 'A', Series (np.random.randn (sLength), index = df1.index))
lowtech
29
Dari Pandas versi 0.12 dan seterusnya, saya percaya sintaks ini tidak optimal, dan memberikan peringatan: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
Zhubarb
6
Mengikuti .loc sebagai peringatan SettingWithCopy, entah bagaimana, menghasilkan lebih banyak peringatan: ... self.obj [item_labels [indexer [info_axis]]] = value
seongjoo
12
@toto_tico Anda dapat membongkar kwargskamus, seperti:df1 = df1.assign(**{'e': p.Series(np.random.randn(sLength)).values})
TC Proctor
23
Alih-alih mengatakan "saat ini" atau merujuk tahun, harap merujuk nomor versi panda, misalnya "antara 0,14-0,16 do X, dalam 0,17+ do Y ..."
smci
229

Ini adalah cara sederhana untuk menambahkan kolom baru: df['e'] = e

Kathirmani Sukumar
sumber
154
Meskipun jumlah suara tinggi: jawaban ini salah . Perhatikan bahwa OP memiliki kerangka data dengan indeks tidak kontinu dan e( Series(np.random.randn(sLength))) menghasilkan Seri 0-n yang diindeks. Jika Anda menetapkan ini ke df1 maka Anda mendapatkan beberapa sel NaN.
joaquin
32
Apa yang dikatakan @ joaquin benar, tetapi selama Anda mengingatnya, ini adalah jalan pintas yang sangat berguna.
VedTopkar
2
@Eric Leschinski: Tidak yakin bagaimana Anda mengedit akan membantu untuk pertanyaan ini. my_dataframe = pd.DataFrame(columns=('foo', 'bar')). Mengembalikan suntingan Anda
Kathirmani Sukumar
1
Itu tidak membantu, karena jika Anda memiliki banyak baris, dan Anda menggunakan tugas, itu menetapkan semua baris kolom baru dengan nilai itu (dalam kasus Anda e) yang biasanya tidak diinginkan.
Paniz
156

Saya ingin menambahkan kolom baru, 'e', ​​ke bingkai data yang ada dan tidak mengubah apa pun di bingkai data. (Seri ini selalu memiliki panjang yang sama dengan bingkai data.)

Saya berasumsi bahwa nilai indeks ecocok dengan yang ada di df1.

Cara termudah untuk memulai kolom baru bernama e, dan berikan nilai dari seri Anda e:

df['e'] = e.values

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.

df1 = df1.assign(e=e.values)

Seperti contoh ini (yang juga menyertakan kode sumber assignfungsi), Anda juga dapat menyertakan lebih dari satu kolom:

df = pd.DataFrame({'a': [1, 2], 'b': [3, 4]})
>>> df.assign(mean_a=df.a.mean(), mean_b=df.b.mean())
   a  b  mean_a  mean_b
0  1  3     1.5     3.5
1  2  4     1.5     3.5

Dalam konteks dengan contoh Anda:

np.random.seed(0)
df1 = pd.DataFrame(np.random.randn(10, 4), columns=['a', 'b', 'c', 'd'])
mask = df1.applymap(lambda x: x <-0.7)
df1 = df1[-mask.any(axis=1)]
sLength = len(df1['a'])
e = pd.Series(np.random.randn(sLength))

>>> df1
          a         b         c         d
0  1.764052  0.400157  0.978738  2.240893
2 -0.103219  0.410599  0.144044  1.454274
3  0.761038  0.121675  0.443863  0.333674
7  1.532779  1.469359  0.154947  0.378163
9  1.230291  1.202380 -0.387327 -0.302303

>>> e
0   -1.048553
1   -1.420018
2   -1.706270
3    1.950775
4   -0.509652
dtype: float64

df1 = df1.assign(e=e.values)

>>> df1
          a         b         c         d         e
0  1.764052  0.400157  0.978738  2.240893 -1.048553
2 -0.103219  0.410599  0.144044  1.454274 -1.420018
3  0.761038  0.121675  0.443863  0.333674 -1.706270
7  1.532779  1.469359  0.154947  0.378163  1.950775
9  1.230291  1.202380 -0.387327 -0.302303 -0.509652

Deskripsi fitur baru ini ketika pertama kali diperkenalkan dapat ditemukan di sini .

Alexander
sumber
2
Adakah komentar tentang kinerja relatif kedua metode, mengingat metode pertama ( df['e'] = e.values) tidak membuat salinan kerangka data, sedangkan opsi kedua (menggunakan df.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.
jhin
2
@ jhin Ya, penugasan langsung jelas jauh jika Anda bekerja pada kerangka data tetap. Manfaat menggunakan assignadalah ketika menyatukan operasi Anda.
Alexander
Ini tentu saja tampak seperti keseimbangan yang baik antara eksplisit dan implisit. +1: D
Abe Hoffman
2
Untuk bersenangdf.assign(**df.mean().add_prefix('mean_'))
piRSquared Tanggal
1
@ Owlright Dari pertanyaan, tampak bahwa OP hanya menyatukan dataframe dan mengabaikan indeks. Jika ini masalahnya, metode di atas akan berfungsi. Jika seseorang ingin mempertahankan indeks, maka gunakan sesuatu seperti df_new = pd.concat([df1, df2], axis=1), mencatatnya ignore_index=Falsesecara default.
Alexander
51

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.

Mikhail Korobov
sumber
1
Menyalin komentar @smci dari atas ... Alih-alih mengatakan "saat ini" atau merujuk tahun, silakan merujuk nomor versi Pandas
Kyle C
50

Melakukan ini secara langsung melalui NumPy akan menjadi yang paling efisien:

df1['e'] = np.random.randn(sLength)

Perhatikan saran asli saya (sangat lama) adalah untuk menggunakan map(yang jauh lebih lambat):

df1['e'] = df1['a'].map(lambda x: np.random.random())
Andy Hayden
sumber
1
terima kasih atas balasan Anda, seperti yang telah saya berikan, dapatkah saya memodifikasi kode Anda, .mapuntuk menggunakan seri yang ada, bukan lambda? Saya mencoba df1['e'] = df1['a'].map(lambda x: e)atau df1['e'] = df1['a'].map(e)tetapi bukan itu yang saya butuhkan. (Saya baru mengenal pyhon dan jawaban Anda sebelumnya sudah membantu saya)
tomasz74
@ tomasz74 jika Anda sudah memiliki eSeri maka Anda tidak perlu menggunakan map, gunakan df['e']=e(@joaquins jawab).
Andy Hayden
49

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 []accessor

    size      name color
0    big      rose   red
1  small    violet  blue
2  small     tulip   red
3  small  harebell  blue

df['protected'] = ['no', 'no', 'no', 'yes']

    size      name color protected
0    big      rose   red        no
1  small    violet  blue        no
2  small     tulip   red        no
3  small  harebell  blue       yes

Perhatikan bahwa ini berfungsi bahkan jika indeks bingkai data tidak aktif.

df.index = [3,2,1,0]
df['protected'] = ['no', 'no', 'no', 'yes']
    size      name color protected
3    big      rose   red        no
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue       yes

[] = adalah cara untuk pergi, tapi hati-hati!

Namun, jika Anda memiliki pd.Seriesdan mencoba untuk menetapkannya ke kerangka data di mana indeks tidak aktif, Anda akan mengalami masalah. Lihat contoh:

df['protected'] = pd.Series(['no', 'no', 'no', 'yes'])
    size      name color protected
3    big      rose   red       yes
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue        no

Ini karena secara pd.Seriesdefault 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.Seriesdan 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.Serieske np.ndarrayatau list, ini akan melakukan trik.

df['protected'] = pd.Series(['no', 'no', 'no', 'yes']).values

atau

df['protected'] = list(pd.Series(['no', 'no', 'no', 'yes']))

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.Seriesmenjadi indeks dfeksplisit.

df['protected'] = pd.Series(['no', 'no', 'no', 'yes'], index=df.index)

Atau lebih realistis, Anda mungkin sudah memiliki pd.Series.

protected_series = pd.Series(['no', 'no', 'no', 'yes'])
protected_series.index = df.index

3     no
2     no
1     no
0    yes

Sekarang bisa ditugaskan

df['protected'] = protected_series

    size      name color protected
3    big      rose   red        no
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue       yes

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.

df.reset_index(drop=True)
protected_series.reset_index(drop=True)
df['protected'] = protected_series

    size      name color protected
0    big      rose   red        no
1  small    violet  blue        no
2  small     tulip   red        no
3  small  harebell  blue       yes

Catatan aktif df.assign

Sementara df.assignmembuatnya lebih eksplisit apa yang Anda lakukan, sebenarnya memiliki semua masalah yang sama seperti di atas[]=

df.assign(protected=pd.Series(['no', 'no', 'no', 'yes']))
    size      name color protected
3    big      rose   red       yes
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue        no

Berhati-hatilah dengan df.assignkolom Anda yang tidak dipanggil self. Itu akan menyebabkan kesalahan. Ini membuat df.assign bau , karena ada jenis artefak dalam fungsinya.

df.assign(self=pd.Series(['no', 'no', 'no', 'yes'])
TypeError: assign() got multiple values for keyword argument 'self'

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.

firelynx
sumber
6
" Ketika Anda menggunakan [] =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?
Lightman
25

Cara termudah: -

data['new_col'] = list_of_values

data.loc[ : , 'new_col'] = list_of_values

Dengan cara ini Anda menghindari apa yang disebut pengindeksan berantai saat menetapkan nilai baru dalam objek panda. Klik di sini untuk membaca lebih lanjut .

Abhishek
sumber
23

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.

menggali digali
sumber
1
ini memunculkan pengaturan tanpa peringatan
00__00__00
1
df ['E'] = '' juga berfungsi jika seseorang ingin menambahkan kolom kosong
debaonline4u
21

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:

df.insert(len(df.columns), 'e', pd.Series(np.random.randn(sLength),  index=df.index))

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.

hum3
sumber
Ini adalah satu-satunya cara yang bekerja untuk saya di 2019!
hydradon
14
  1. Pertama buat python list_of_eyang memiliki data yang relevan.
  2. Gunakan ini: df['e'] = list_of_e
Sumit Pokhrel
sumber
1
Saya benar-benar tidak mengerti, mengapa ini bukan jawaban yang disukai. Jika Anda memiliki pd.Series, tolist()perintahnya mungkin membantu.
Jadi S
11

Jika kolom yang Anda coba tambahkan adalah variabel seri maka cukup:

df["new_columns_name"]=series_variable_name #this will do it for you

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.

Akshay Singhvi
sumber
10

Jika bingkai data dan objek Seri memiliki indeks yang sama , pandas.concatjuga berfungsi di sini:

import pandas as pd
df
#          a            b           c           d
#0  0.671399     0.101208   -0.181532    0.241273
#1  0.446172    -0.243316    0.051767    1.577318
#2  0.614758     0.075793   -0.451460   -0.012493

e = pd.Series([-0.335485, -1.166658, -0.385571])    
e
#0   -0.335485
#1   -1.166658
#2   -0.385571
#dtype: float64

# here we need to give the series object a name which converts to the new  column name 
# in the result
df = pd.concat([df, e.rename("e")], axis=1)
df

#          a            b           c           d           e
#0  0.671399     0.101208   -0.181532    0.241273   -0.335485
#1  0.446172    -0.243316    0.051767    1.577318   -1.166658
#2  0.614758     0.075793   -0.451460   -0.012493   -0.385571

Jika mereka tidak memiliki indeks yang sama:

e.index = df.index
df = pd.concat([df, e.rename("e")], axis=1)
Psidom
sumber
10

Sangat mudah:

df.loc[:, 'NewCol'] = 'New_Val'

Contoh:

df = pd.DataFrame(data=np.random.randn(20, 4), columns=['A', 'B', 'C', 'D'])

df

           A         B         C         D
0  -0.761269  0.477348  1.170614  0.752714
1   1.217250 -0.930860 -0.769324 -0.408642
2  -0.619679 -1.227659 -0.259135  1.700294
3  -0.147354  0.778707  0.479145  2.284143
4  -0.529529  0.000571  0.913779  1.395894
5   2.592400  0.637253  1.441096 -0.631468
6   0.757178  0.240012 -0.553820  1.177202
7  -0.986128 -1.313843  0.788589 -0.707836
8   0.606985 -2.232903 -1.358107 -2.855494
9  -0.692013  0.671866  1.179466 -1.180351
10 -1.093707 -0.530600  0.182926 -1.296494
11 -0.143273 -0.503199 -1.328728  0.610552
12 -0.923110 -1.365890 -1.366202 -1.185999
13 -2.026832  0.273593 -0.440426 -0.627423
14 -0.054503 -0.788866 -0.228088 -0.404783
15  0.955298 -1.430019  1.434071 -0.088215
16 -0.227946  0.047462  0.373573 -0.111675
17  1.627912  0.043611  1.743403 -0.012714
18  0.693458  0.144327  0.329500 -0.655045
19  0.104425  0.037412  0.450598 -0.923387


df.drop([3, 5, 8, 10, 18], inplace=True)

df

           A         B         C         D
0  -0.761269  0.477348  1.170614  0.752714
1   1.217250 -0.930860 -0.769324 -0.408642
2  -0.619679 -1.227659 -0.259135  1.700294
4  -0.529529  0.000571  0.913779  1.395894
6   0.757178  0.240012 -0.553820  1.177202
7  -0.986128 -1.313843  0.788589 -0.707836
9  -0.692013  0.671866  1.179466 -1.180351
11 -0.143273 -0.503199 -1.328728  0.610552
12 -0.923110 -1.365890 -1.366202 -1.185999
13 -2.026832  0.273593 -0.440426 -0.627423
14 -0.054503 -0.788866 -0.228088 -0.404783
15  0.955298 -1.430019  1.434071 -0.088215
16 -0.227946  0.047462  0.373573 -0.111675
17  1.627912  0.043611  1.743403 -0.012714
19  0.104425  0.037412  0.450598 -0.923387

df.loc[:, 'NewCol'] = 0

df
           A         B         C         D  NewCol
0  -0.761269  0.477348  1.170614  0.752714       0
1   1.217250 -0.930860 -0.769324 -0.408642       0
2  -0.619679 -1.227659 -0.259135  1.700294       0
4  -0.529529  0.000571  0.913779  1.395894       0
6   0.757178  0.240012 -0.553820  1.177202       0
7  -0.986128 -1.313843  0.788589 -0.707836       0
9  -0.692013  0.671866  1.179466 -1.180351       0
11 -0.143273 -0.503199 -1.328728  0.610552       0
12 -0.923110 -1.365890 -1.366202 -1.185999       0
13 -2.026832  0.273593 -0.440426 -0.627423       0
14 -0.054503 -0.788866 -0.228088 -0.404783       0
15  0.955298 -1.430019  1.434071 -0.088215       0
16 -0.227946  0.047462  0.373573 -0.111675       0
17  1.627912  0.043611  1.743403 -0.012714       0
19  0.104425  0.037412  0.450598 -0.923387       0
K88
sumber
2
Tidak mudah. Ini tidak menjawab pertanyaan OP, yang merupakan kasus di mana indeks dari kerangka data yang ada dan seri baru tidak selaras.
Alexander
7

Biarkan saya tambahkan saja, seperti untuk hum3 , .loctidak menyelesaikan SettingWithCopyWarningdan saya harus menggunakan df.insert(). Dalam kasus saya false positive dihasilkan oleh pengindeksan rantai "palsu" dict['a']['e'], di mana 'e'kolom baru, dan dict['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.

kkumer
sumber
7

untuk menyisipkan kolom baru di lokasi tertentu (0 <= loc <= jumlah kolom) dalam bingkai data, cukup gunakan Dataframe.insert:

DataFrame.insert(loc, column, value)

Oleh karena itu, jika Anda ingin menambahkan kolom e di akhir bingkai data yang disebut df , Anda dapat menggunakan:

e = [-0.335485, -1.166658, -0.385571]    
DataFrame.insert(loc=len(df.columns), column='e', value=e)

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

Nooyi
sumber
6

Sebelum menetapkan kolom baru, jika Anda memiliki data yang diindeks, Anda perlu mengurutkan indeks. Setidaknya dalam kasus saya, saya harus:

data.set_index(['index_column'], inplace=True)
"if index is unsorted, assignment of a new column will fail"        
data.sort_index(inplace = True)
data.loc['index_value1', 'column_y'] = np.random.randn(data.loc['index_value1', 'column_x'].shape[0])
Dima Lituiev
sumber
6

Satu hal yang perlu diperhatikan, adalah jika Anda melakukannya

df1['e'] = Series(np.random.randn(sLength), index=df1.index)

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,

data = pd.DataFrame(index=all_possible_values)
df1['e'] = Series(np.random.randn(sLength), index=df1.index)
WillZ
sumber
5

Saya sedang mencari cara umum untuk menambahkan kolom numpy.nans ke dalam dataframe tanpa menjadi bodoh SettingWithCopyWarning.

Dari berikut ini:

  • jawabannya di sini
  • pertanyaan ini tentang meneruskan variabel sebagai argumen kata kunci
  • metode ini untuk menghasilkan numpyarray NaNs in-line

Saya datang dengan ini:

col = 'column_name'
df = df.assign(**{col:numpy.full(len(df), numpy.nan)})
ryanjdillon
sumber
4

Untuk menambahkan kolom baru, 'e', ​​ke bingkai data yang ada

 df1.loc[:,'e'] = Series(np.random.randn(sLength))
Chirag
sumber
Itu juga memberikan pesan peringatan
B Furtado
Anda harus menggunakan df1.loc [::, 'e'] = Series (np.random.randn (sLength))
Hermes Morales
4

Demi kelengkapan - solusi lain menggunakan metode DataFrame.eval () :

Data:

In [44]: e
Out[44]:
0    1.225506
1   -1.033944
2   -0.498953
3   -0.373332
4    0.615030
5   -0.622436
dtype: float64

In [45]: df1
Out[45]:
          a         b         c         d
0 -0.634222 -0.103264  0.745069  0.801288
4  0.782387 -0.090279  0.757662 -0.602408
5 -0.117456  2.124496  1.057301  0.765466
7  0.767532  0.104304 -0.586850  1.051297
8 -0.103272  0.958334  1.163092  1.182315
9 -0.616254  0.296678 -0.112027  0.679112

Larutan:

In [46]: df1.eval("e = @e.values", inplace=True)

In [47]: df1
Out[47]:
          a         b         c         d         e
0 -0.634222 -0.103264  0.745069  0.801288  1.225506
4  0.782387 -0.090279  0.757662 -0.602408 -1.033944
5 -0.117456  2.124496  1.057301  0.765466 -0.498953
7  0.767532  0.104304 -0.586850  1.051297 -0.373332
8 -0.103272  0.958334  1.163092  1.182315  0.615030
9 -0.616254  0.296678 -0.112027  0.679112 -0.622436
MaxU
sumber
4

Untuk membuat kolom kosong

df['i'] = None
JNZ
sumber
3

Berikut ini adalah apa yang saya lakukan ... Tapi saya cukup baru untuk panda dan benar-benar Python secara umum, jadi tidak ada janji.

df = pd.DataFrame([[1, 2], [3, 4], [5,6]], columns=list('AB'))

newCol = [3,5,7]
newName = 'C'

values = np.insert(df.values,df.shape[1],newCol,axis=1)
header = df.columns.values.tolist()
header.append(newName)

df = pd.DataFrame(values,columns=header)
Devin Charles
sumber
3

Jika Anda mendapatkan SettingWithCopyWarning, perbaikan yang mudah adalah menyalin DataFrame yang Anda coba tambahkan kolom.

df = df.copy()
df['col_name'] = values
fredcallaway
sumber
10
itu bukan ide yang bagus. Jika kerangka data cukup besar, ini akan menjadi intensif memori ... Selain itu akan berubah menjadi mimpi buruk jika Anda terus menambahkan kolom sesekali.
Kevad