我目前有一个形状为 (16280, 13) 的 DataFrame。我想将值分配给单列中的特定行。我最初是这样做的:
for idx, row in enumerate(df.to_dict('records')):
instances = row['instances']
labels = row['labels'].split('|')
for instance in instances:
if instance not in relevant_labels:
labels = ['O' if instance in l else l for l in labels]
df.iloc[idx]['labels'] = '|'.join(labels)
但这一直返回 SettingWithCopyWarning
由于最后一行。我尝试将其更改为 df.loc[idx, 'labels'] = '|'.join(labels)
它不再返回警告,但在我的代码的后面部分导致了错误。
我注意到使用 iloc
时 DataFrame 的大小为 (16280, 13)和 (16751, 13) 当使用 loc
时.
如何防止打印警告并获得与使用 iloc
相同的功能?
最佳答案
您有很多方面可以改进。
首先,尽量不要循环数据帧,而是使用 pandas 包提供的一些工具。
但是,如果无法避免,最好使用 .iterrows()
对数据帧的行进行循环。方法而不是 .to_dict()
。请记住,如果使用 iterrows
,您不应在迭代时修改数据框。
然后,供 iloc/loc 使用。 Loc 使用键名称(如字典),尽管 iloc 使用键索引(如数组)。这里idx
是一个索引,而不是键的名称,那么df.loc[idx, 'labels']
如果键的名称与其索引不同,将会导致一些错误。我们可以轻松地使用它们,如下所示:df.iloc[idx, : ].loc['labels']
.
为了说明loc
之间的区别和iloc
:
df_example = pd.DataFrame({"a": [1, 2, 3, 4],
"b": ['a', 'b', 'a', 'b']},
index=[0, 1, 3, 5])
print(df_example.loc[0] == df_example.iloc[0]) # 0 is the first key, loc and iloc same results
print(df_example.loc[1] == df_example.iloc[1]) # 1 is the second key, loc and iloc same results
try:
print(df_example.loc[2] == df_example.iloc[2]) # 2 is not a key, then it will crash on loc (Keyerror)
except KeyError:
pass
print(df_example.loc[3] == df_example.iloc[3]) # 3 the third key, then iloc and loc will lead different results
try:
print(df_example.loc[5] == df_example.iloc[5]) # 5 is the last key but there is no 6th key so it will crash on iloc (indexerror)
except IndexError:
pass
请记住,链接数据帧将返回数据的副本而不是切片:doc 。这就是为什么 df.iloc[idx]['labels']
和df.iloc[idx, : ].loc['labels']
将触发警告。如果labels
是你的第 i 列,df.iloc[idx, i ]
不会触发警告。
关于python - 使用 iloc 和 loc 将新值分配给行会产生不同的结果。如何避免与 iloc 相同的SettingToCopyWarning?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74383862/