No puedo entender cómo establecer el valor de una Serie en un índice específico en un estilo encadenable.
Por ejemplo, supongamos que tengo el siguiente marco de datos:
>>> df = pd.DataFrame({'a': [1,2,3], 'b': [0,0,0]}) >>> df ab 0 1 0 1 2 0 2 3 0 Si quiero cambiar todos los valores de una columna en una canalización, puedo usar pandas.DataFrame.assign() :
>>> df.assign(b=[4,5,6]) ab 0 1 4 1 2 5 2 3 6... y luego puedo hacer otras cosas con el marco de datos en la misma línea, por ejemplo:
>>> df.assign(b=[4,5,6]).mul(100) ab 0 100 400 1 200 500 2 300 600Pero no puedo hacer esto por un valor individual en una serie específica.
>>> s = df['a'] >>> s 0 1 1 2 2 3 Name: a, dtype: int64 Puedo, por supuesto, simplemente usar una operación de asignación de Python normal usando = :
>>> s[1] = 9 >>> s 0 1 1 9 2 3 Name: a, dtype: int64Pero los problemas con eso son:
= no están permitidas en las funciones lambda de PythonPor ejemplo, qué pasaría si quisiera hacer esto:
>>> df.apply(lambda x: x['b', 0] = 13, axis=1) File "<stdin>", line 1 df.apply(lambda x: x['b', 0] = 13, axis=1) ^ SyntaxError: expression cannot contain assignment, perhaps you meant "=="?(Entiendo que hay mejores formas para ese caso en particular, pero esto es solo un ejemplo inventado).
¿Cómo puedo establecer el valor en el índice especificado de una Serie? Me gustaría poder hacer algo como s.set_value(idx, 'my_val') y hacer que devuelva la Serie modificada (copiada).
Puede usar pandas.Series.where() para devolver una copia de la columna con el elemento en el índice especificado.
Esto es básicamente como usar .loc :
>>> df['b'].where(df['b'].index != 1, 13) 0 0 1 13 2 0 Name: b, dtype: int64 Si tiene un índice que no es un RangeIndex o que no comienza desde cero, puede llamar a reset_index() antes de where() , que será como el anterior para .loc solo imitando el comportamiento de .iloc en su lugar:
>>> s = pd.Series({'a': 0, None: 0, True: 0}) >>> s a 0 NaN 0 True 0 dtype: int64 >>> s.where(s.reset_index().index != 1, 13) a 0 NaN 13 True 0 dtype: int64