当我运行这个玩具代码时
test = pd.DataFrame({'a': [1, 2, 3, 4]})
test['b'] = ''
for i in range(len(test)):
test['b'].loc[i] = [5, 6, 7]
我收到警告
SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
self._setitem_single_block(indexer, value, name)
但如果我按照这种方法使用loc
test = pd.DataFrame({'a': [1, 2, 3, 4]})
test['b'] = ''
for i in range(len(test)):
test.loc[i, 'b'] = [5, 6, 7]
我收到一个错误
ValueError: Must have equal len keys and value when setting with an iterable
这个错误是什么意思?特别是,它引用了哪些键、值和可迭代性?
您可以使用apply
:
test['b'] = test['b'].apply(lambda x: [5, 6, 7])
或列表串联(或列表理解(:
test['b'] = [[5, 6, 7]] * len(test)
如果必须使用循环,可以使用at
(这很有效,因为您通过最初将''
分配给"b"
来将其设置为dtype对象,并且只要类型匹配,at
就可以为单元格分配值(:
for i in range(len(test)):
test.at[i, 'b'] = [5, 6, 7]
输出:
a b
0 1 [5, 6, 7]
1 2 [5, 6, 7]
2 3 [5, 6, 7]
3 4 [5, 6, 7]
之所以会发生这种情况,是因为在第二段代码中,您试图根据索引号而不是列名来设置值。
如果你这样做:
for i in range(len(test)):
print(test.loc[i])
这给了你:
a 1
b
Name: 0, dtype: object
a 2
b
Name: 1, dtype: object
a 3
b
Name: 2, dtype: object
a 4
b
Name: 3, dtype: object
这意味着使用loc和i变量,在索引上按行访问它,这就是为什么会出现不匹配的len错误。
要克服此警告,请特别使用loc
:导航到该列
test = pd.DataFrame({'a': [1, 2, 3, 4]})
test['b'] = ''
for i in range(len(test)):
test.loc[:,'b'].loc[i] = [5, 6, 7]