例如我有
df=pd.DataFrame({'a':[1,2,3]})
df[df['a']==3].a = 4
这不会将4分配给3是
df[df['a']==3] = 4
但这很有效。
让我对作业如何运作感到困惑。感谢是否有人可以给我一些参考或解释。
答案 0 :(得分:3)
你不想要使用第二种方法。它返回一个数据帧子切片,并为每一行分配相同的值。
例如,
df
a b
0 1 4
1 2 3
2 3 6
df[df['a'] == 3]
a b
2 3 6
df[df['a']==3] = 3
df
a b
0 1 4
1 2 3
2 3 3
第一种方法不起作用,因为布尔索引返回了您要分配给的列(系列)的副本,因此赋值失败:
df[df['a'] == 3].a = 4
/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/pandas/core/generic.py:3110: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
self[name] = value
因此,您的选项使用基于索引的.loc
(按名称访问)或iloc
(按索引访问):
df.loc[df.a == 3, 'a'] = 4
df
a
0 1
1 2
2 4
如果您传递的是布尔掩码,则无法使用iloc
。
答案 1 :(得分:2)
将.loc
与布尔索引和列标签选择一起使用:
df.loc[df.a == 3,'a'] = 4
print(df)
输出:
a
0 1
1 2
2 4
在您的方法中,发生的事情是您正在切割数据帧,并且pandas正在创建副本,并且该分配发生在数据帧的副本而不是原始数据帧本身。
答案 2 :(得分:1)
使用loc
In [1289]: df.loc[df['a']==3, 'a'] = 4
In [1290]: df
Out[1290]:
a
0 1
1 2
2 4
答案 3 :(得分:1)
或者你可以这样做
df['a'] = df['a'].replace(3, 4)
(修改,谢谢@COLDSPEED)
答案 4 :(得分:0)
你想做什么
df['a'].apply(lambda x: 4 if x ==3 else x)
会给出:
0 1
1 2
2 4