Panda python menyisipkan daftar ke dalam sel

105

Saya memiliki daftar 'abc' dan dataframe 'df':

abc = ['foo', 'bar']
df =
    A  B
0  12  NaN
1  23  NaN

Saya ingin memasukkan daftar ke sel 1B, jadi saya ingin hasil ini:

    A  B
0  12  NaN
1  23  ['foo', 'bar']

Ho bisakah saya melakukan itu?

1) Jika saya menggunakan ini:

df.ix[1,'B'] = abc

Saya mendapatkan pesan kesalahan berikut:

ValueError: Must have equal len keys and value when setting with an iterable

karena mencoba memasukkan daftar (yang memiliki dua elemen) ke dalam baris / kolom tetapi tidak ke dalam sel.

2) Jika saya menggunakan ini:

df.ix[1,'B'] = [abc]

kemudian menyisipkan daftar yang hanya memiliki satu elemen yaitu 'abc' list ( [['foo', 'bar']]).

3) Jika saya menggunakan ini:

df.ix[1,'B'] = ', '.join(abc)

lalu menyisipkan string: ( foo, bar) tetapi bukan daftar.

4) Jika saya menggunakan ini:

df.ix[1,'B'] = [', '.join(abc)]

lalu itu menyisipkan daftar tetapi hanya memiliki satu elemen ( ['foo, bar']) tetapi tidak dua seperti yang saya inginkan ( ['foo', 'bar']).

Terimakasih atas bantuannya!


EDIT

Dataframe baru saya dan daftar lama:

abc = ['foo', 'bar']
df2 =
    A    B         C
0  12  NaN      'bla'
1  23  NaN  'bla bla'

Dataframe lain:

df3 =
    A    B         C                    D
0  12  NaN      'bla'  ['item1', 'item2']
1  23  NaN  'bla bla'        [11, 12, 13]

Saya ingin memasukkan daftar 'abc' ke df2.loc[1,'B']dan / atau df3.loc[1,'B'].

Jika kerangka data memiliki kolom hanya dengan nilai integer dan / atau nilai NaN dan / atau nilai daftar, maka memasukkan daftar ke dalam sel bekerja dengan sempurna. Jika kerangka data memiliki kolom hanya dengan nilai string dan / atau nilai NaN dan / atau nilai daftar, maka memasukkan daftar ke dalam sel bekerja dengan sempurna. Tetapi jika dataframe memiliki kolom dengan nilai integer dan string dan kolom lainnya maka muncul pesan kesalahan jika saya menggunakan ini: df2.loc[1,'B'] = abcatau df3.loc[1,'B'] = abc.

Dataframe lain:

df4 =
          A     B
0      'bla'  NaN
1  'bla bla'  NaN

Sisipan ini bekerja dengan sempurna: df.loc[1,'B'] = abcatau df4.loc[1,'B'] = abc.

ragesz
sumber
1
Panda versi apa yang Anda gunakan? berikut ini bekerja menggunakan panda 0.15.0:df.loc[1,'b'] = ['foo','bar']
EdChum
Terima kasih! Saya menggunakan Python 2.7 dan saya mencoba pandas 0.14.0 dan 0.15.0 dan bekerja dengan data uji di atas. Tetapi bagaimana jika saya memiliki kolom 'C' juga dengan beberapa nilai integer? 'A' memiliki string. Memiliki kolom integer dan kolom srting saya mendapatkan kesalahan yang sama: ValueError: Harus memiliki kunci dan nilai len yang sama saat mengatur dengan iterable
ragesz
Anda harus memposting data dan kode untuk menjelaskan dan menunjukkan apa yang Anda maksud
EdChum

Jawaban:

119

Karena set_valuesudah tidak digunakan lagi sejak versi 0.21.0, sekarang Anda harus menggunakan at. Itu dapat memasukkan daftar ke dalam sel tanpa meningkatkan ValueErrorseperti yang locdilakukannya. Saya rasa ini karena at selalu mengacu pada satu nilai, sementara locdapat merujuk pada nilai serta baris dan kolom.

df = pd.DataFrame(data={'A': [1, 2, 3], 'B': ['x', 'y', 'z']})

df.at[1, 'B'] = ['m', 'n']

df =
    A   B
0   1   x
1   2   [m, n]
2   3   z

Anda juga perlu memastikan kolom yang Anda masukkan memiliki dtype=object. Sebagai contoh

>>> df = pd.DataFrame(data={'A': [1, 2, 3], 'B': [1,2,3]})
>>> df.dtypes
A    int64
B    int64
dtype: object

>>> df.at[1, 'B'] = [1, 2, 3]
ValueError: setting an array element with a sequence

>>> df['B'] = df['B'].astype('object')
>>> df.at[1, 'B'] = [1, 2, 3]
>>> df
   A          B
0  1          1
1  2  [1, 2, 3]
2  3          3
Michael Hays
sumber
4
Saya harus memastikan dtype dataframe asli disetel ke objek agar ini berfungsi:df = pd.DataFrame(data, dtype=object)
Takver
2
di membutuhkan indeks. Bagaimana cara merujuk ke baris menggunakan kecocokan nilai atribut lainnya; Misal: untuk baris dengan A = 2 pada contoh di atas?
bikashg
8
Ini mengembalikan kesalahan lain ValueError: setting an array element with a sequence.; lihat jawaban oleh @ cs95 jika Anda mendapatkan kesalahan.
Blaszard
39

df3.set_value(1, 'B', abc)berfungsi untuk kerangka data apa pun. Jaga tipe data kolom 'B'. Misalnya. daftar tidak dapat dimasukkan ke dalam kolom float, dalam hal ini df['B'] = df['B'].astype(object)dapat membantu.

ragesz
sumber
6
Perhatikan bahwa perintah ini sudah tidak digunakan lagi . Ada pembaruan tepat di bawah.
Thomas
35

Panda> = 0,21

set_valuesudah tidak digunakan lagi. Anda sekarang dapat menggunakan DataFrame.atto set by label, dan DataFrame.iatto set by integer position.

Mengatur Nilai Sel dengan at/iat

# Setup
df = pd.DataFrame({'A': [12, 23], 'B': [['a', 'b'], ['c', 'd']]})
df

    A       B
0  12  [a, b]
1  23  [c, d]

df.dtypes

A     int64
B    object
dtype: object

Jika Anda ingin menetapkan nilai di baris kedua "B" ke beberapa daftar baru, gunakan DataFrane.at:

df.at[1, 'B'] = ['m', 'n']
df

    A       B
0  12  [a, b]
1  23  [m, n]

Anda juga dapat mengatur dengan posisi integer menggunakan DataFrame.iat

df.iat[1, df.columns.get_loc('B')] = ['m', 'n']
df

    A       B
0  12  [a, b]
1  23  [m, n]

Bagaimana jika saya mendapatkan ValueError: setting an array element with a sequence?

Saya akan mencoba mereproduksi ini dengan:

df

    A   B
0  12 NaN
1  23 NaN

df.dtypes

A      int64
B    float64
dtype: object

df.at[1, 'B'] = ['m', 'n']
# ValueError: setting an array element with a sequence.

Ini karena objek Anda float64berjenis d, sedangkan daftar adalah objects, jadi ada ketidakcocokan di sana. Apa yang harus Anda lakukan dalam situasi ini adalah mengonversi kolom menjadi objek terlebih dahulu.

df['B'] = df['B'].astype(object)
df.dtypes

A     int64
B    object
dtype: object

Kemudian, ini berhasil:

df.at[1, 'B'] = ['m', 'n']
df

    A       B
0  12     NaN
1  23  [m, n]

Mungkin, Tapi Hacky

Yang lebih aneh lagi, saya menemukan Anda dapat meretas DataFrame.locuntuk mencapai sesuatu yang serupa jika Anda melewati daftar bersarang.

df.loc[1, 'B'] = [['m'], ['n'], ['o'], ['p']]
df

    A             B
0  12        [a, b]
1  23  [m, n, o, p]

Anda dapat membaca lebih lanjut tentang mengapa ini berfungsi di sini.

cs95
sumber
2

Bekerja cepat

Cukup lampirkan daftar di dalam daftar baru, seperti yang dilakukan untuk col2 dalam bingkai data di bawah ini. Alasan kerjanya adalah karena python mengambil daftar terluar (dari daftar) dan mengubahnya menjadi kolom seolah-olah itu berisi item skalar normal, yang merupakan daftar dalam kasus kami dan bukan skalar normal.

mydict={'col1':[1,2,3],'col2':[[1, 4], [2, 5], [3, 6]]}
data=pd.DataFrame(mydict)
data


   col1     col2
0   1       [1, 4]
1   2       [2, 5]
2   3       [3, 6]
Pallavi Jindal
sumber
0

Juga mendapatkan

ValueError: Must have equal len keys and value when setting with an iterable,

menggunakan .at daripada .loc tidak membuat perbedaan apa pun dalam kasus saya, tetapi memaksakan tipe data kolom dataframe melakukan trik:

df['B'] = df['B'].astype(object)

Kemudian saya bisa mengatur daftar, array numpy dan segala macam hal sebagai nilai sel tunggal dalam kerangka data saya.

Maxime Beau
sumber