2

我有一个DataFramedf 和一个dictd,如下所示:

>>> df
   a   b
0  5  10
1  6  11
2  7  12
3  8  13
4  9  14
>>> d = {6: 22, 8: 26}

对于(key, val)字典中的每一个,我想找到列a与键匹配的行,并用值覆盖它的b列。例如,在这种特殊情况下,b第 1 行的值将更改为 22,第 3 行的值将更改为 26。

我该怎么做?

4

1 回答 1

2

假设可以将新值传播到列匹配的所有a(如果 column 中有重复项a),则:

for a_val, b_val in d.iteritems():
    df['b'][df.a==a_val] = b_val

或避免链接赋值操作:

for a_val, b_val in d.iteritems():
    df.loc[df.a==a_val, 'b'] = b_val

请注意,要使用loc您必须使用 Pandas 0.11 或更高版本。对于较旧的版本,您可能可以使用.ix来防止链式分配。

@Jeff 指向此链接,该链接讨论了我在此评论中已经提到的一种现象。请注意,这不是正确性问题,因为颠倒访问顺序具有可预测的效果。您可以很容易地看到这一点,例如:

In [102]: id(df[df.a==5]['b'])
Out[102]: 113795992

In [103]: id(df['b'][df.a==5])
Out[103]: 113725760

如果您先获取列,然后根据索引分配到该列,则更改会影响该列。由于该列是 DataFrame 的一部分,因此更改会影响 DataFrame。如果您首先索引一组行,您现在不再谈论相同的 DataFrame,因此从过滤对象中获取列不会让您看到原始列。

@Jeff 建议这使它“不正确”,而我的观点是这是显而易见的预期行为。在特殊情况下,当您有一个混合数据类型列并且正在进行某些类型提升/降级时会阻止 Pandas 将值写入该列,那么您可能会遇到正确性问题。但鉴于loc直到 Pandas 0.11 才可用,我认为指出如何通过链式赋值来做到这一点仍然是公平的,而不是假装喜欢loc是唯一可能是正确选择的事情。

如果有人可以提供更明确的理由认为它是“不正确的”(而不是在文体上不喜欢这个),请贡献,我将尝试对各种陷阱进行更全面的描述。

于 2013-10-01T20:52:44.703 回答