You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas .loc()赋值触发TypeError: Must provide strings错误的解决方法

问题

我有一个尺寸为(36484909, 113)的DataFrame model_data_utsset,执行以下代码时,第三、四行的.loc()操作正常,但第五行赋值时返回TypeError: Must provide strings错误。已确认列表feats仅包含字符串列名,且.loc()返回的DataFrame与数组dummy形状一致,使用的Pandas版本为2.2.0。

代码片段:

from sklearn.preprocessing import RobustScaler
scaler = RobustScaler()
trans = scaler.fit(model_data_utsset.loc[model_data_utsset['cmdb_ci']==ci, feats])
dummy = trans.transform(model_data_utsset.loc[ model_data_utsset['cmdb_ci']==ci, feats])
model_data_utsset.loc[model_data_utsset['cmdb_ci']==ci, feats] = dummy

完整报错回溯:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_3506448/3789644235.py in <module>
      5     dummy = trans.transform(model_data_utsset.loc[ model_data_utsset['cmdb_ci']==ci, feats])
----> 6     model_data_utsset.loc[model_data_utsset['cmdb_ci']==ci, feats] = dummy
      7     print(len(model_data_utsset.loc[model_data_utsset['cmdb_ci']==ci, feats]))

~/.local/lib/python3.9/site-packages/pandas/core/indexing.py in __setitem__(self, key, value)
    910 
    911         iloc = self if self.name == "iloc" else self.obj.iloc
---> 912         iloc._setitem_with_indexer(indexer, value, self.name)
    913 
    914     def _validate_key(self, key, axis: AxisInt):

~/.local/lib/python3.9/site-packages/pandas/core/indexing.py in _setitem_with_indexer(self, indexer, value, name)
   1944         if take_split_path:
   1945             # We have to operate column-wise
-> 1946             self._setitem_with_indexer_split_path(indexer, value, name)
   1947         else:
   1948             self._setitem_single_block(indexer, value, name)

~/.local/lib/python3.9/site-packages/pandas/core/indexing.py in _setitem_with_indexer_split_path(self, indexer, value, name)
   1984                 # TODO: avoid np.ndim call in case it isn't an ndarray, since
   1985                 #  that will construct an ndarray, which will be wasteful
-> 1986                 self._setitem_with_indexer_2d_value(indexer, value)
   1987 
   1988             elif len(ilocs) == 1 and lplane_indexer == len(value) and not is_scalar(pi):

~/.local/lib/python3.9/site-packages/pandas/core/indexing.py in _setitem_with_indexer_2d_value(self, indexer, value)
   2059                 # casting to list so that we do type inference in setitem_single_column
   2060                 value_col = value_col.tolist()
-> 2061             self._setitem_single_column(loc, value_col, pi)
   2062 
   2063     def _setitem_with_indexer_frame_value(self, indexer, value: DataFrame, name: str):

~/.local/lib/python3.9/site-packages/pandas/core/indexing.py in _setitem_single_column(self, loc, value, plane_indexer)
   2166             # set value into the column (first attempting to operate inplace, then
   2167             #  falling back to casting if necessary)
-> 2168             self.obj._mgr.column_setitem(loc, plane_indexer, value)
   2169 
   2170         self.obj._clear_item_cache()

~/.local/lib/python3.9/site-packages/pandas/core/internals/managers.py in column_setitem(self, loc, idx, value, inplace_only)
   1336             col_mgr.setitem_inplace(idx, value)
   1337         else:
-> 1338             new_mgr = col_mgr.setitem((idx,), value)
   1339             self.iset(loc, new_mgr._block.values, inplace=True)
   1340 

~/.local/lib/python3.9/site-packages/pandas/core/internals/managers.py in setitem(self, indexer, value, warn)
    414             self = self.copy()
    415 
-> 416         return self.apply("setitem", indexer=indexer, value=value)
    417 
    418     def diff(self, n: int) -> Self:

~/.local/lib/python3.9/site-packages/pandas/core/internals/managers.py in apply(self, f, align_keys, **kwargs)
    362                 applied = b.apply(f, **kwargs)
    363             else:
-> 364                 applied = getattr(b, f)(**kwargs)
    365             result_blocks = extend_blocks(applied, result_blocks)
    366 

~/.local/lib/python3.9/site-packages/pandas/core/internals/blocks.py in setitem(self, indexer, value, using_cow)
   2054 
   2055         try:
-> 2056             values[indexer] = value
   2057         except (ValueError, TypeError):
   2058             if isinstance(self.dtype, IntervalDtype):

~/.local/lib/python3.9/site-packages/pandas/core/arrays/string_.py in __setitem__(self, key, value)
    467                 value = np.asarray(value, dtype=object)
    468             if len(value) and not lib.is_string_array(value, skipna=True):
-> 469                 raise TypeError("Must provide strings.")
    470 
    471             mask = isna(value)

TypeError: Must provide strings.
解决方案

问题根源

报错来自Pandas的StringArray类型校验:你要赋值的feats列是String dtype,但RobustScaler.transform()输出的是数值型numpy数组,直接赋值会触发字符串类型的强制校验,导致报错。

具体解决方法

方法1:提前将目标列转为数值类型

在预处理前,把feats列转为适合数值操作的类型(比如float64),从根源解决类型不匹配问题:

# 先转换列类型
model_data_utsset[feats] = model_data_utsset[feats].astype('float64')

# 再执行缩放和赋值
scaler = RobustScaler()
trans = scaler.fit(model_data_utsset.loc[model_data_utsset['cmdb_ci']==ci, feats])
dummy = trans.transform(model_data_utsset.loc[model_data_utsset['cmdb_ci']==ci, feats])
model_data_utsset.loc[model_data_utsset['cmdb_ci']==ci, feats] = dummy

方法2:将dummy转为DataFrame后赋值

把numpy数组转为和目标子集索引、列名完全匹配的DataFrame,让Pandas自动处理类型兼容逻辑:

from sklearn.preprocessing import RobustScaler
import pandas as pd

scaler = RobustScaler()
# 先提取目标子集,避免重复写条件
subset = model_data_utsset.loc[model_data_utsset['cmdb_ci']==ci, feats]
trans = scaler.fit(subset)
dummy = trans.transform(subset)

# 转为DataFrame,复用原子集的索引和列名
dummy_df = pd.DataFrame(dummy, index=subset.index, columns=subset.columns)
model_data_utsset.loc[model_data_utsset['cmdb_ci']==ci, feats] = dummy_df

方法3:直接赋值底层values(快速绕过类型检查)

如果确认数值类型安全,可以直接赋值numpy数组的底层值,跳过部分Pandas的类型校验:

model_data_utsset.loc[model_data_utsset['cmdb_ci']==ci, feats] = dummy.values

验证建议

操作前可以先检查feats列的 dtype,确认是否为字符串类型:

print(model_data_utsset[feats].dtypes)

如果显示string,优先用方法1转换类型;如果是数值类型仍报错,可检查列中是否混入了字符串格式的无效值。

内容的提问来源于stack exchange,提问作者Mark Pundurs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:59:51