Python pandas вставить список в ячейку

107

У меня есть список 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']).

Спасибо за помощь!


РЕДАКТИРОВАТЬ

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

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.

ragesz
источник
1
Какую версию панды вы используете? с использованием панд работало следующее 0.15.0:df.loc[1,'b'] = ['foo','bar']
EdChum
Спасибо! Я использую Python 2.7, пробовал pandas 0.14.0 и 0.15.0, и он работал с тестовыми данными выше. Но что, если у меня есть столбец «C» с некоторыми целочисленными значениями? У «А» есть струны. Имея целочисленный столбец и столбец srting, я получаю ту же ошибку: ValueError: должны иметь одинаковые ключи len и значение при настройке с помощью итерации
ragesz
Вам нужно будет опубликовать данные и код, чтобы объяснить и показать, что вы имеете в виду
EdChum

Ответы:

122

Поскольку set_valueон устарел с версии 0.21.0, теперь вы должны использовать at. Он может вставлять список в ячейку, не поднимая a, 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 фрейма данных был установлен как object, чтобы это работало:df = pd.DataFrame(data, dtype=object)
Takver
2
at нужен индекс. Как сослаться на строку, используя совпадение значения другого атрибута; например: для строки с A = 2 в приведенном выше примере?
bikashg 05
9
Это возвращает другую ошибку ValueError: setting an array element with a sequence.; см. ответ @ cs95, если вы получили сообщение об ошибке.
Blaszard 05
41

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

ragesz
источник
6
Обратите внимание, что эта команда устарела . Прямо внизу есть обновление.
Thomas
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]

Вы можете узнать больше о том, почему это работает здесь.

cs95
источник
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 и все остальное как значения отдельных ячеек в моих фреймах данных.

Максим Бо
источник