Панда Python вставляє список у клітинку


105

У мене є список 'abc' і фрейм даних 'df':

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

Я хочу вставити список у комірку 1B, тому хочу такий результат:

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

Хо я можу це зробити?

1) Якщо я використовую це:

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

Я отримую таке повідомлення про помилку:

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

оскільки він намагається вставити список (який має два елементи) у рядок / стовпець, але не в клітинку.

2) Якщо я використовую це:

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

потім він вставляє список, який має лише один елемент, який є списком 'abc' ( [['foo', 'bar']]).

3) Якщо я використовую це:

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

тоді він вставляє рядок: ( foo, bar), але не список.

4) Якщо я використовую це:

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

потім він вставляє список, але він має лише один елемент ( ['foo, bar']), але не два, як я хочу ( ['foo', 'bar']).

Дякуємо за допомогу!


EDIT

Мій новий фрейм даних і старий список:

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

Інший фрейм даних:

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

Я хочу вставити список "abc" у df2.loc[1,'B']та / або df3.loc[1,'B'].

Якщо фрейм даних має стовпці лише із цілими значеннями та / або значеннями NaN та / або значеннями списку, тоді вставлення списку в комірку працює ідеально. Якщо фрейм даних має стовпці лише зі значеннями рядків та / або значеннями NaN та / або значеннями списку, тоді вставлення списку в комірку працює ідеально. Але якщо в фреймі даних є стовпці із цілими і рядковими значеннями та іншими стовпцями, тоді з'являється повідомлення про помилку, якщо я використовую це: df2.loc[1,'B'] = abcабо df3.loc[1,'B'] = abc.

Інший фрейм даних:

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

Ці вставки чудово працюють: df.loc[1,'B'] = abcабо df4.loc[1,'B'] = abc.


1
Яку версію панд ви використовуєте? з використанням панд працювали 0.15.0:df.loc[1,'b'] = ['foo','bar']
EdChum

Дякую! Я використовую Python 2.7, і я спробував панди 0,14,0 та 0,15,0, і це працювало з вищезазначеними тестовими даними. Але що, якщо у мене також є стовпець "C" з деякими цілими значеннями? 'A' має рядки. Маючи цілочисельний стовпець та стовпчик srting, я отримую однакову помилку: ValueError: Повинні мати рівні ключі і значення len при встановленні з ітерабельним
ragesz

Вам потрібно буде розмістити дані та код, щоб пояснити та показати, що ви маєте на увазі
EdChum

Відповіді:


119

Так set_valueбуло застарілим , починаючи з версії 0.21.0, тепер ви повинні використовувати at. Він може вставити список в клітку не піднімаючи , ValueErrorяк locробить. Я думаю, це тому, що at завжди посилається на одне значення, тоді як locможе посилатися на значення, а також на рядки та стовпці.

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

Вам також потрібно переконатися, що стовпець, який ви вставляєте, має dtype=object. Наприклад

>>> 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

4
Мені довелося переконатись, що оригінальний тип даних фрейму dtype був встановлений таким чином, щоб це працювало:df = pd.DataFrame(data, dtype=object)
Таквер

2
при потребі індекс. Як я можу звернутися до рядка, використовуючи інше значення збігу значень атрибута; наприклад: для рядка з A = 2 у наведеному вище прикладі?
bikashg

8
Це повертає ще одну помилку ValueError: setting an array element with a sequence.; див. відповідь @ cs95, якщо ви отримали помилку.
Blaszard

39

df3.set_value(1, 'B', abc)працює для будь-якого фрейму даних. Подбайте про тип даних стовпця "B". Напр. список не можна вставити в плаваючу колонку, і в цьому випадку це df['B'] = df['B'].astype(object)може допомогти.


6
Зверніть увагу, що ця команда застаріла . Оновлення знаходиться внизу.
Томас

35

Панда> = 0,21

set_valueзастаріло. Тепер ви можете використовувати DataFrame.atдля встановлення за міткою та DataFrame.iatдля цілочисельної позиції.

Встановлення значень комірок за допомогою 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

Якщо ви хочете встановити значення у другому рядку "B" до якогось нового списку, використовуйте DataFrane.at:

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

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

Ви також можете встановити цілу позицію за допомогою DataFrame.iat

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

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

Що, якщо я отримаю ValueError: setting an array element with a sequence?

Я спробую відтворити це за допомогою:

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.

Це пов’язано з тим, що ваш об’єкт має float64тип dtype, тоді як списки - objects, тож там є невідповідність. Що б вам потрібно було зробити в цій ситуації, це перетворити стовпець на об’єкт спочатку.

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

A     int64
B    object
dtype: object

Тоді це працює:

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

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

Можливо, але хакі

Навіть більш химерним, я виявив, що ви можете зламати DataFrame.locщось подібне, якщо передасте вкладені списки.

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

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

Детальніше про те, чому це працює, ви можете прочитати тут.



2

Швидка робота

Просто додайте список до нового списку, як це зроблено для col2 у фреймі даних нижче. Причина, по якій це працює, полягає в тому, що python бере зовнішній список (списків) і перетворює його в стовпець, ніби він містить нормальні елементи скалярів, що в нашому випадку є списками, а не звичайними скалярами.

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]

0

Також отримую

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

використання .at, а не .loc, у моєму випадку не змінило ситуації, але застосування типу даних стовпця dataframe зробило трюк:

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

Тоді я міг би встановити списки, масив numpy та всілякі речі як значення по одній комірці у своїх кадрах даних.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.