Python panda: mengisi baris data baris demi baris

133

Tugas sederhana untuk menambahkan baris ke pandas.DataFrameobjek tampaknya sulit untuk diselesaikan. Ada 3 pertanyaan stackoverflow yang berkaitan dengan ini, tidak ada yang memberikan jawaban yang berfungsi.

Inilah yang saya coba lakukan. Saya memiliki DataFrame yang saya sudah tahu bentuknya serta nama-nama baris dan kolom.

>>> df = pandas.DataFrame(columns=['a','b','c','d'], index=['x','y','z'])
>>> df
     a    b    c    d
x  NaN  NaN  NaN  NaN
y  NaN  NaN  NaN  NaN
z  NaN  NaN  NaN  NaN

Sekarang, saya memiliki fungsi untuk menghitung nilai-nilai baris secara iteratif. Bagaimana saya bisa mengisi salah satu baris dengan kamus atau pandas.Series? Berikut adalah berbagai upaya yang gagal:

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df['y'] = y
AssertionError: Length of values does not match length of index

Tampaknya ia mencoba menambahkan kolom alih-alih satu baris.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.join(y)
AttributeError: 'builtin_function_or_method' object has no attribute 'is_unique'

Pesan kesalahan sangat tidak informatif.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.set_value(index='y', value=y)
TypeError: set_value() takes exactly 4 arguments (3 given)

Rupanya itu hanya untuk menetapkan nilai individual dalam kerangka data.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.append(y)
Exception: Can only append a Series if ignore_index=True

Yah, saya tidak ingin mengabaikan indeks, jika tidak, inilah hasilnya:

>>> df.append(y, ignore_index=True)
     a    b    c    d
0  NaN  NaN  NaN  NaN
1  NaN  NaN  NaN  NaN
2  NaN  NaN  NaN  NaN
3    1    5    2    3

Itu memang menyelaraskan nama kolom dengan nilai-nilai, tetapi kehilangan label baris.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.ix['y'] = y
>>> df
                                  a                                 b  \
x                               NaN                               NaN
y  {'a': 1, 'c': 2, 'b': 5, 'd': 3}  {'a': 1, 'c': 2, 'b': 5, 'd': 3}
z                               NaN                               NaN

                                  c                                 d
x                               NaN                               NaN
y  {'a': 1, 'c': 2, 'b': 5, 'd': 3}  {'a': 1, 'c': 2, 'b': 5, 'd': 3}
z                               NaN                               NaN

Itu juga gagal total.

Jadi, bagaimana Anda melakukannya?

xApple
sumber

Jawaban:

92

df['y'] akan mengatur kolom

karena Anda ingin mengatur baris, gunakan .loc

Catatan yang .ixsetara di sini, milik Anda gagal karena Anda mencoba menetapkan kamus untuk setiap elemen baris ymungkin bukan yang Anda inginkan; mengonversi ke Seri memberi tahu panda bahwa Anda ingin menyelaraskan input (misalnya Anda tidak harus menentukan semua elemen)

In [7]: df = pandas.DataFrame(columns=['a','b','c','d'], index=['x','y','z'])

In [8]: df.loc['y'] = pandas.Series({'a':1, 'b':5, 'c':2, 'd':3})

In [9]: df
Out[9]: 
     a    b    c    d
x  NaN  NaN  NaN  NaN
y    1    5    2    3
z  NaN  NaN  NaN  NaN
Jeff
sumber
Saya melihat. Jadi locatribut dari frame data mendefinisikan spesial __setitem__yang melakukan keajaiban kurasa.
xApple
Bisakah Anda membuat ini dalam satu pass (yaitu dengan kolom, indeks dan y)?
Andy Hayden
5
Jadi jika saya dapat menghasilkan satu baris pada satu waktu, bagaimana cara saya membuat kerangka data secara optimal?
xApple
Apakah mengharapkan beberapa varian df = pd.DataFrame({'y': pd.Series(y)}, columns=['a','b','c','d'], index=['x','y','z'])untuk bekerja?
Andy Hayden
@xApple prob terbaik bagi Anda untuk membangun daftar dicts (atau daftar), kemudian hanya meneruskan ke konstruktor, akan jauh lebih efisien
Jeff
71

Pendekatan saya adalah, tetapi saya tidak dapat menjamin bahwa ini adalah solusi tercepat.

df = pd.DataFrame(columns=["firstname", "lastname"])
df = df.append({
     "firstname": "John",
     "lastname":  "Johny"
      }, ignore_index=True)
mengalir
sumber
4
Ini bekerja dengan baik untuk saya dan saya menyukai kenyataan bahwa Anda secara eksplisit appenddata ke kerangka data.
Jonny Brooks
1
Perhatikan bahwa jawaban ini membutuhkan setiap baris untuk menambahkan nama kolom. Sama untuk jawaban yang diterima.
pashute
Ini juga berfungsi jika Anda tidak tahu jumlah baris sebelumnya.
irene
34

Ini adalah versi yang lebih sederhana

import pandas as pd
df = pd.DataFrame(columns=('col1', 'col2', 'col3'))
for i in range(5):
   df.loc[i] = ['<some value for first>','<some value for second>','<some value for third>']`
Satheesh
sumber
4
hanya ingin bertanya, apakah CPU dan memori ini efisien?
czxttkl
1
bagaimana saya tahu baris terakhir df jadi saya menambahkan ke baris terakhir setiap kali?
pashute
25

Jika baris input Anda adalah daftar dan bukan kamus, maka berikut ini adalah solusi sederhana:

import pandas as pd
list_of_lists = []
list_of_lists.append([1,2,3])
list_of_lists.append([4,5,6])

pd.DataFrame(list_of_lists, columns=['A', 'B', 'C'])
#    A  B  C
# 0  1  2  3
# 1  4  5  6
stackoverflowuser2010
sumber
tetapi apa yang harus saya lakukan jika saya memiliki indeks multi? df1 = pd.DataFrame (list_of_lists, kolom ['A', 'B', 'C'], index = ['A', 'B']) tidak berfungsi. Bentuknya salah. Jadi bagaimana?
pashute