def canbe_float(x: float= 0):
    try:
        float(x)
        return True
    except (ValueError, NameError, TypeError):  # None
        return False

# 早期的方法
def to_float(df: pd.core.frame.DataFrame = pd.DataFrame({"c1":[1.1,np.nan],"c2":[3.1,"?"]})): # 函数在import之后
    for i in df: # 遍历每一列
        seri_bool = df.loc[:,i].apply(canbe_float) # 判断该列内的每个元素
        df.loc[seri_bool,i] = df.loc[seri_bool,i].astype('float64').astype(str) # 筛选并转化格式
    return df

# 严谨的方法
def to_float(df: pd.core.frame.DataFrame= pd.DataFrame({"c1":[1.1,np.nan],"c2":[3.1,"?"]})):  # 函数在import之后
    for i in range(df.shape[1]):  # 遍历每一列(避免列名重复,采用位置索引)
        ser_bool = df.iloc[:,i].apply(canbe_float)  # 判断该列内的每个元素
        # 筛选结果为Series可用.astype('float64'), 否则为单个位置的元素, 需用float()
        for j in range(df.shape[0]):  # 遍历每一行(采用位置索引)
            if ser_bool[j]:  # 如果该列的该行元素判断为真
                df.iloc[j, i] = float(df.iloc[j, i])
            else:
                df.iloc[j, i] = np.nan
    return df

# 更快的方法
def to_float(df: pd.core.frame.DataFrame= pd.DataFrame({"c1":[1.1,np.nan],"c2":[3.1,"?"]})):  # 函数在import之后
    df_result = df.copy()
    for i in range(df.shape[1]):  # 遍历每一列(避免列名重复,采用位置索引)
        # 筛选结果为Series可用.astype('float64'), 否则为单个位置的元素, 需用float()
        ColName = df.columns[i]  # 避免DeprecationWarning df.iloc[:, i] = newvals df[df.columns[i]] (若列名重复则错位)
        df_result[ColName] = df.iloc[:,i].apply(lambda x: float(x) if canbe_float(x) else np.nan)
    return df_result

https://blog.51cto.com/u_16055028/6438781