含空值pandas DataFrame写入Cassandra报float无encode属性错误
错误根因
触发'float' object has no attribute 'encode'的核心原因是类型不匹配:
- 你建表时将所有字段都定义为
varchar类型,Cassandra Python驱动写入varchar字段时,会自动对传入值调用.encode()方法做编码转换,但浮点类型对象没有这个方法,直接传入就会报错。 - pandas读取CSV时,数值列默认会被解析为float/int类型,且所有缺失值默认填充为
np.nan(本质是浮点类型),这两类值直接传给预编译的插入语句就会触发错误。 - 你之前尝试的两个方案完全不匹配问题场景:
pd.read_csv的encoding_error参数只处理CSV文件读取阶段的文本编码问题,和写入数据库的类型错误无关;直接用str()转浮点值时如果没有覆盖所有列、也没有特殊处理np.nan,要么漏转数值列,要么会把空值转成字符串'nan'存入数据库,无法解决根本问题。
修复步骤
- 第一步:在拼接完train和test的DataFrame后,统一处理所有字段的类型和空值
如果你保留全字段varchar的建表逻辑,执行以下代码即可:
如果需要把空值存为空字符串而非null,把最后一行的# 替换所有空值为None(Cassandra识别为null,不会触发encode错误),非空值统一转字符串 df = df.where(pd.notna(df), None) for col in df.columns: df[col] = df[col].apply(lambda x: str(x) if x is not None else None)None改成空字符串''即可。 - 第二步:修复批量写入逻辑
你当前把所有数据塞进单个BatchStatement的写法会触发Cassandra单批次大小上限(默认阈值50KB),还容易引发超时问题,改成按固定小批次写入:from cassandra.query import BatchStatement from cassandra import ConsistencyLevel columns = "Item_Identifier, Item_Weight, Item_Fat_Content, Item_Visibility, Item_Type, Item_MRP, Outlet_Identifier, Outlet_Establishment_Year, Outlet_Size, Outlet_Location_Type, Outlet_Type, Item_Outlet_Sales, source" insert_qry = f"INSERT INTO {table_}({columns}) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)" prepared = session.prepare(insert_qry) # 可根据业务场景调整一致性级别 prepared.consistency_level = ConsistencyLevel.LOCAL_ONE # 单批次建议控制在100-500条,避免超过批次大小限制 batch_size = 200 for start in range(0, len(df), batch_size): batch = BatchStatement() current_batch = df.iloc[start:start+batch_size] for _, row in current_batch.iterrows(): batch.add(prepared, tuple(row.values)) session.execute(batch) - 可选优化:调整建表字段类型,减少不必要的类型转换
对于本身是数值的字段(比如Item_Weight、Item_Visibility、Item_MRP、Outlet_Establishment_Year、Item_Outlet_Sales),建表时直接定义为对应数值类型(float/int),不需要转成字符串写入,既能避免类型错误,还能节省存储、提升查询效率。对应建表字段定义参考:
这种场景下不需要做字符串转换,只需要把DataFrame里的define_columns = """ Item_Identifier varchar PRIMARY KEY, Item_Weight float, Item_Fat_Content varchar, Item_Visibility float, Item_Type varchar, Item_MRP float, Outlet_Identifier varchar, Outlet_Establishment_Year int, Outlet_Size varchar, Outlet_Location_type varchar, Outlet_Type varchar, Item_Outlet_Sales float, source varchar """np.nan替换成None即可:df = df.where(pd.notna(df), None)
内容的提问来源于stack exchange,提问作者Manu Vats
相关产品推荐
相关产品推荐

