如何将缺失值的列转换为字符串?

问题描述 投票:0回答:3

我需要使用 SQL Alchemy 将数据帧从 pandas 导出到 Microsoft SQL Server。许多列都是字符串,缺少值和一些非常长的整数,例如999999999999999999999999999999999 。这些数字是某种外键,因此值本身没有任何意义,因此我可以将它们转换为字符串。

尝试导出到 SQL 时,这会导致 SQL Alchemy 中出现以下错误:

OverflowError: int too big to convert

我尝试使用

astype(str)
转换为字符串,但后来遇到了一个问题,即标识为 nans 的缺失值被转换为字符串“nan” - 因此 SQL 不会将它们视为空值,而是将其视为字符串“nan” .

我找到的唯一解决方案是首先转换为 str,然后用

numpy.nan
替换 'nan'。有更好的方法吗? 这很麻烦,相对较慢,并且尽可能不Python:首先我将所有内容都转换为字符串,转换将空值转换为字符串,所以我将它们转换为 NaN,它只能是浮点数,我最终得到了一个混合类型的列。

或者我是否必须忍气吞声并接受 pandas 在处理缺失值方面很糟糕?

我有一个例子如下:

import numpy as np, pandas as pd, time

from sqlalchemy import create_engine, MetaData, Table, select
import sqlalchemy as sqlalchemy

start=time.time()
ServerName = "DESKTOP-MRX\SQLEXPRESS"
Database = 'MYDATABASE'
params = '?driver=SQL+Server+Native+Client+11.0'
engine = create_engine('mssql+pyodbc://' + ServerName + '/'+ Database + params, encoding ='latin1' )
conn=engine.connect()

df=pd.DataFrame()
df['mixed']=np.arange(0,9)
df.iloc[0,0]='test'
df['numb']=3.0
df['text']='my string'
df.iloc[0,2]=np.nan
df.iloc[1,2]=999999999999999999999999999999999

df['text']=df['text'].astype(str).replace('nan',np.nan)

df.to_sql('test_df_mixed_types', engine, schema='dbo', if_exists='replace')
python sql-server pandas string nan
3个回答
21
投票

使用

np.where
肯定会比替换更快一点,即

df['text'] = np.where(pd.isnull(df['text']),df['text'],df['text'].astype(str))

时间:

%%timeit
df['text'].astype(str).replace('nan',np.nan)
1000 loops, best of 3: 536 µs per loop

%%timeit
np.where(pd.isnull(df['text']),df['text'],df['text'].astype(str))
1000 loops, best of 3: 274 µs per loop

x = pd.concat([df['text']]*10000)
%%timeit
np.where(pd.isnull(x),x,x.astype(str))
10 loops, best of 3: 28.8 ms per loop

%%timeit
x.astype(str).replace('nan',np.nan)
10 loops, best of 3: 33.5 ms per loop

1
投票

要将 NaN 保留为 NaN 并仅将非 NaN 行转换为

str
,请使用布尔索引。

msk = df['text'].notna()
df.loc[msk, 'text'] = df.loc[msk, 'text'].astype(str)

或使用

mask()
方法根据条件(值是否为非 NaN)选择值,非常类似于
np.where()

df['text'] = df['text'].mask(lambda x: x.notna(), df['text'].astype(str))

但是,如果您想将 NaN 变成空字符串(也许稍后要对字符串进行操作),那么请使用

fillna()

df['text'] = df['text'].fillna('').astype(str)

0
投票

熊猫=楠 楠 -> 空

db_update = db_update.replace({np.nan: None})
© www.soinside.com 2019 - 2024. All rights reserved.