Solución:
Ya que set_value
ha quedado obsoleto desde la versión 0.21.0, ahora debería usar at
. Puede insertar una lista en una celda sin generar un ValueError
como loc
lo hace. Creo que esto es porque at
siempre se refiere a un solo valor, mientras que loc
puede referirse tanto a valores como a filas y columnas.
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
También debe asegurarse de columna estás insertando en has dtype=object
. Por ejemplo
>>> 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
df3.set_value(1, 'B', abc)
funciona para cualquier marco de datos. Tenga cuidado con el tipo de datos de la columna ‘B’. P.ej. una lista no se puede insertar en una columna flotante, en ese caso df['B'] = df['B'].astype(object)
poder ayudar.
Pandas> = 0,21
set_value
ha quedado obsoleto. Ahora puedes usar DataFrame.at
para configurar por etiqueta, y DataFrame.iat
para establecer por posición entera.
Establecer valores de celda con 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
Si desea establecer un valor en la segunda fila de la “B” para alguna lista nueva, use DataFrane.at
:
df.at[1, 'B'] = ['m', 'n']
df
A B
0 12 [a, b]
1 23 [m, n]
También puede establecer por posición entera usando DataFrame.iat
df.iat[1, df.columns.get_loc('B')] = ['m', 'n']
df
A B
0 12 [a, b]
1 23 [m, n]
Que pasa si consigo ValueError: setting an array element with a sequence
?
Intentaré reproducir esto con:
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.
Esto se debe a que su objeto es de float64
dtype, mientras que las listas son object
s, por lo que hay un desajuste allí. Lo que tendría que hacer en esta situación es convertir la columna en objeto primero.
df['B'] = df['B'].astype(object)
df.dtypes
A int64
B object
dtype: object
Entonces, funciona:
df.at[1, 'B'] = ['m', 'n']
df
A B
0 12 NaN
1 23 [m, n]
Posible, pero hacky
Aún más loco, he descubierto que puedes hackear DataFrame.loc
para lograr algo similar si pasa listas anidadas.
df.loc[1, 'B'] = [['m'], ['n'], ['o'], ['p']]
df
A B
0 12 [a, b]
1 23 [m, n, o, p]
Puede leer más sobre por qué esto funciona aquí.