如何以可链接的样式将系列的值设置为特定值?

How can I set the value of a Series at a specific in a chainable style?

我不知道如何以可链接的方式在特定索引处设置 Series 的值。

例如,假设我有以下数据框:

>>> df = pd.DataFrame({'a': [1,2,3], 'b': [0,0,0]})
>>> df
   a  b
0  1  0
1  2  0
2  3  0

如果我想更改管道中某一列的所有值,我可以使用 pandas.DataFrame.assign():

>>> df.assign(b=[4,5,6])
   a  b
0  1  4
1  2  5
2  3  6

...然后我可以在同一行使用数据框做其他事情,例如:

>>> df.assign(b=[4,5,6]).mul(100)
     a    b
0  100  400
1  200  500
2  300  600

但我不能为系列中特定的单个值执行此操作。

>>> s = df['a']
>>> s
0    1
1    2
2    3
Name: a, dtype: int64

当然,我可以使用 =:

使用正常的 Python 赋值操作
>>> s[1] = 9
>>> s
0    1
1    9
2    3
Name: a, dtype: int64

但问题是:

例如,如果我想这样做怎么办:

>>> 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 "=="?

(我知道对于这种特殊情况有更好的方法,但这只是一个虚构的例子。)

如何在系列的指定索引处设置值? 我希望能够像 s.set_value(idx, 'my_val') 这样的东西并拥有它 return 修改(复制)系列。

您可以使用 pandas.Series.where() 来 return 具有指定索引处的项目的列的副本。

这基本上就像使用 .loc:

>>> df['b'].where(df['b'].index != 1, 13)
0     0
1    13
2     0
Name: b, dtype: int64

如果你有一个索引不是 RangeIndex 或者不是从零开始,你可以在 where() 之前调用 reset_index(),就像上面那样因为 .loc 只是模仿 .iloc 的行为,而不是:

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