Sisipkan baris ke bingkai data pandas

112

Saya memiliki kerangka data:

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

   A  B  C
0  5  6  7
1  7  8  9

[2 rows x 3 columns]

dan saya perlu menambahkan baris pertama [2, 3, 4] untuk mendapatkan:

   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

Saya sudah mencoba append()dan concat()berfungsi tetapi tidak dapat menemukan cara yang tepat untuk melakukannya.

Bagaimana cara menambahkan / memasukkan seri ke dataframe?

Meloun
sumber
6
perhatikan bahwa lebih baik menggunakan s1.valuesdaripada list(s1)karena Anda akan membuat daftar yang sama sekali baru menggunakan list(s1).
acushner
7
Saya tidak mengerti mengapa semua orang sangat menyukai panda, padahal sesuatu yang seharusnya sangat sederhana adalah menyebalkan dan sangat lambat.
MattCochrane

Jawaban:

145

Cukup tetapkan baris ke indeks tertentu, menggunakan loc:

 df.loc[-1] = [2, 3, 4]  # adding a row
 df.index = df.index + 1  # shifting index
 df = df.sort_index()  # sorting by index

Dan Anda mendapatkan, seperti yang diinginkan:

    A  B  C
 0  2  3  4
 1  5  6  7
 2  7  8  9

Lihat di Pengindeksan dokumentasi Pandas : Pengaturan dengan pembesaran .

Piotr Migdal
sumber
2
Jika Anda tidak ingin menyetel dengan pembesaran, tetapi menyisipkan di dalam kerangka data, lihat stackoverflow.com/questions/15888648/…
FooBar
6
pergeseran indeks alternatif: df.sort (). reset_index (drop = True)
Meloun
2
df.sort tidak digunakan lagi, gunakan df.sort_index ()
GBGOLC
1
@Piotr - ini berfungsi dengan baik, tetapi apa yang terjadi ketika Anda ingin menduplikasi baris dari bingkai data Anda, seperti df.loc[-1] = df.iloc[[0]], dan menyisipkan itu? Bingkai dilengkapi dengan kolom indeks tambahan yang memberikan kesalahan ValueError: cannot set a row with mismatched columns (lihat stackoverflow.com/questions/47340571/… )
Growler
5
Saya pikir df.loc[-1] = [2, 3, 4] # adding a rowagak menyesatkan, karena -1bukan baris / elemen terakhir, seperti untuk array Python.
flow2k
26

Tidak yakin bagaimana Anda memanggilnya concat()tetapi itu harus bekerja selama kedua objek memiliki tipe yang sama. Mungkin masalahnya adalah Anda perlu mentransmisikan vektor kedua ke bingkai data? Menggunakan df yang Anda tentukan berikut ini berfungsi untuk saya:

df2 = pd.DataFrame([[2,3,4]], columns=['A','B','C'])
pd.concat([df2, df])
mgilbert.dll
sumber
Jawaban terbaik ^ :)
Cam.Davidson.Pilon
23

Salah satu cara untuk mencapainya adalah

>>> pd.DataFrame(np.array([[2, 3, 4]]), columns=['A', 'B', 'C']).append(df, ignore_index=True)
Out[330]: 
   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

Umumnya, yang paling mudah adalah menambahkan kerangka data, bukan seri. Dalam kasus Anda, karena Anda ingin baris baru menjadi "di atas" (dengan id awal), dan tidak ada fungsipd.prepend() , pertama-tama saya membuat kerangka data baru dan kemudian menambahkan yang lama.

ignore_indexakan mengabaikan indeks lama yang sedang berlangsung di dataframe Anda dan memastikan bahwa baris pertama benar-benar dimulai dengan indeks 1alih-alih memulai ulang dengan indeks0 .

Penafian Umum: Cetero censeo ... menambahkan baris adalah operasi yang sangat tidak efisien. Jika Anda peduli dengan kinerja dan entah bagaimana dapat memastikan untuk terlebih dahulu membuat kerangka data dengan indeks yang benar (lebih panjang) dan kemudian hanya memasukkan baris tambahan ke dalam kerangka data, Anda pasti harus melakukannya. Lihat:

>>> index = np.array([0, 1, 2])
>>> df2 = pd.DataFrame(columns=['A', 'B', 'C'], index=index)
>>> df2.loc[0:1] = [list(s1), list(s2)]
>>> df2
Out[336]: 
     A    B    C
0    5    6    7
1    7    8    9
2  NaN  NaN  NaN
>>> df2 = pd.DataFrame(columns=['A', 'B', 'C'], index=index)
>>> df2.loc[1:] = [list(s1), list(s2)]

Sejauh ini, kami memiliki apa yang Anda miliki sebagai df:

>>> df2
Out[339]: 
     A    B    C
0  NaN  NaN  NaN
1    5    6    7
2    7    8    9

Tetapi sekarang Anda dapat dengan mudah memasukkan baris sebagai berikut. Karena ruang telah dialokasikan sebelumnya, ini lebih efisien.

>>> df2.loc[0] = np.array([2, 3, 4])
>>> df2
Out[341]: 
   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9
FooBar
sumber
Itu solusi kerja yang bagus, saya mencoba memasukkan seri ke dalam kerangka data. Cukup bagus untukku saat ini.
Meloun
Saya paling suka opsi terakhir. Ini benar-benar cocok dengan apa yang benar-benar ingin saya lakukan. Terima kasih @FooBar!
Jade Cacho
13

Saya mengumpulkan fungsi pendek yang memungkinkan sedikit lebih banyak fleksibilitas saat menyisipkan baris:

def insert_row(idx, df, df_insert):
    dfA = df.iloc[:idx, ]
    dfB = df.iloc[idx:, ]

    df = dfA.append(df_insert).append(dfB).reset_index(drop = True)

    return df

yang selanjutnya dapat disingkat menjadi:

def insert_row(idx, df, df_insert):
    return df.iloc[:idx, ].append(df_insert).append(df.iloc[idx:, ]).reset_index(drop = True)

Kemudian Anda bisa menggunakan sesuatu seperti:

df = insert_row(2, df, df_new)

di mana 2posisi indeks di dfmana Anda ingin menyisipkan df_new.

elPastor
sumber
7

Kita bisa gunakan numpy.insert. Ini memiliki keunggulan fleksibilitas. Anda hanya perlu menentukan indeks yang ingin Anda sisipkan.

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

pd.DataFrame(np.insert(df.values, 0, values=[2, 3, 4], axis=0))

    0   1   2
0   2   3   4
1   5   6   7
2   7   8   9

Karena np.insert(df.values, 0, values=[2, 3, 4], axis=0), 0 memberi tahu fungsi tempat / indeks yang Anda inginkan untuk menempatkan nilai baru.

Tai
sumber
6

ini mungkin tampak terlalu sederhana tetapi luar biasa bahwa fungsi baris baru sisipkan sederhana tidak built in. Saya telah membaca banyak tentang menambahkan df baru ke aslinya, tapi saya bertanya-tanya apakah ini akan lebih cepat.

df.loc[0] = [row1data, blah...]
i = len(df) + 1
df.loc[i] = [row2data, blah...]
Aaron Melgar
sumber
Apakah yang Anda maksud adalah "menambahkan df baru" atau hanya "menambahkan baris baru", seperti yang ditunjukkan kode Anda?
smci
maaf kalimat saya tidak jelas. Saya telah membaca solusi orang lain yang menggabungkan / menambahkan kerangka data baru hanya dengan satu baris. tetapi dalam solusi saya, ini hanya satu baris dalam kerangka data yang ada, tidak perlu dibuat kerangka data tambahan
Aaron Melgar
6

Di bawah ini akan menjadi cara terbaik untuk menyisipkan baris ke dalam bingkai data panda tanpa mengurutkan dan menyetel ulang indeks:

import pandas as pd

df = pd.DataFrame(columns=['a','b','c'])

def insert(df, row):
    insert_loc = df.index.max()

    if pd.isna(insert_loc):
        df.loc[0] = row
    else:
        df.loc[insert_loc + 1] = row

insert(df,[2,3,4])
insert(df,[8,9,0])
print(df)
Sagar Rathod
sumber
mengapa Anda mengatakan ini adalah cara terbaik?
Yuca
maka alangkah baiknya memberikan bukti untuk mendukung klaim tersebut, apakah Anda menentukan waktunya?
Yuca
1
Anda dapat menggunakan pd.isna untuk menghindari pengimporan numpy
kato2
2

Sangat mudah untuk menambahkan baris ke dalam panda DataFrame:

  1. Buat kamus Python biasa dengan nama kolom yang sama seperti milik Anda Dataframe;

  2. Gunakan pandas.append()metode dan berikan nama kamus Anda, di mana .append()metode pada instance DataFrame;

  3. Tambahkan ignore_index=Truetepat setelah nama kamus Anda.

Pepe
sumber
Ini mungkin opsi yang paling disukai (sekitar tahun 2020).
David Golembiowski
1

concat()tampaknya sedikit lebih cepat daripada penyisipan dan pengindeksan ulang baris terakhir. Jika seseorang bertanya-tanya tentang kecepatan dua pendekatan teratas:

In [x]: %%timeit
     ...: df = pd.DataFrame(columns=['a','b'])
     ...: for i in range(10000):
     ...:     df.loc[-1] = [1,2]
     ...:     df.index = df.index + 1
     ...:     df = df.sort_index()

17.1 s ± 705 ms per loop (rata-rata ± std. Dev. Dari 7 run, masing-masing 1 loop)

In [y]: %%timeit
     ...: df = pd.DataFrame(columns=['a', 'b'])
     ...: for i in range(10000):
     ...:     df = pd.concat([pd.DataFrame([[1,2]], columns=df.columns), df])

6,53 s ± 127 ms per loop (rata-rata ± std. Dev. Dari 7 run, masing-masing 1 loop)

M. Viaz
sumber
0

Anda cukup menambahkan baris ke akhir DataFrame, lalu menyesuaikan indeks.

Misalnya:

df = df.append(pd.DataFrame([[2,3,4]],columns=df.columns),ignore_index=True)
df.index = (df.index + 1) % len(df)
df = df.sort_index()

Atau gunakan concatsebagai:

df = pd.concat([pd.DataFrame([[1,2,3,4,5,6]],columns=df.columns),df],ignore_index=True)
Xinyi Li
sumber
-1

Cara termudah menambahkan baris dalam bingkai data pandas adalah:

DataFrame.loc[ location of insertion ]= list( )

Contoh:

DF.loc[ 9 ] = [ ´Pepe , 33, ´Japan ]

NB: panjang daftar Anda harus sesuai dengan bingkai data.

Pepe
sumber
melakukan trik untuk saya!
Sam Shaw