1、替换换行符等特殊符号
df = df.replace({None: "", np.nan: "", "\t": "", "\n": "", "\x08": ""}, regex=True)
2、清除DataFrame中所有数据的左右空格,字符串中间空格不会清除,类似于字符串的strip()方法,如果是Serise类型可以使用df.str.strip()方法
df = df.applymap(lambda x: " ".join(x.split()) if isinstance(x, str) else x)
3、dataframe数据去重
dataframe数据样本:
import pandas as pd
df = pd.DataFrame({'name':['苹果','梨','草莓','苹果'], 'price':[7,8,9,8], 'cnt':[3,4,5,4]})
name cnt price
0 苹果 3 7
1 梨 4 8
2 草莓 5 9
3 苹果 6 8
3.1、查看dataframe的重复数据
a = df.groupby('price').count()>1
price = a[a['cnt'] == True].index
repeat_df = df[df['price'].isin(price)]
3.2、duplicated()方法判断
3.2.1、 判断dataframe数据某列是否重复
flag = df.price.duplicated()
0 False
1 False
2 False
3 True
Name: price, dtype: bool
flag.any()结果为True (any等于对flag or判断)
flag.all()结果为False (all等于对flag and判断)
3.2.2、判断dataframe数据整行是否重复
flag = df.duplicated()
判断方法同1
3.2.3、判断dataframe数据多列数据是否重复(多列组合查)
df.duplicated(subset = ['price','cnt'])
判断方法同1
3.3、 drop_duplicats()方法去重
对dataframe数据数据去重
DataFrame.drop_duplicates(subset=None, keep='first', inplace=False)
示例:
df.drop_duplicats(subset = ['price','cnt'],keep='last',inplace=True)
drop_duplicats参数说明:
参数subset
subset用来指定特定的列,默认所有列
参数keep
keep可以为first和last,表示是选择最前一项还是最后一项保留,默认first
参数inplace
inplace是直接在原来数据上修改还是保留一个副本,默认为False
4、 文件中含有换行符时,需要保留换行符
import csv
import pandas as pd
#
data = {'col1': ['Hello\nWorld', 'Line\nbreak"'], 'col2': [1, 2]}
df = pd.DataFrame(data)
print(df)
df.to_csv('data.csv', line_terminator='\n', quoting=csv.QUOTE_ALL, index=False, header=False)
df = pd.read_csv('data.csv', header=None)
print(df)
运行结果:

5、当csv文件入hive时,遇到空值需要在hive中显示为null值
CREATE TABLE my_table
(
id int comment '编号',
name string comment '名称',
money decimal(10, 2) comment '金钱'
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
NULL DEFINED AS ''
STORED AS TEXTFILE
TBLPROPERTIES ("serialization.null.format"='');
NULL DEFINED AS ''将空字符串视为NULL值,'serialization.null.format'=''则用于指定NULL值在数据文件中的表示方式。通过这种方式,我们可以同时使用NULL DEFINED AS ''和serialization.null.format=''来将NULL值和空字符串表示在Hive中的一致性。
也可以修改已存在的表,如下
alter table my_table set serdeproperties('serialization.null.format' = '');
6、pandas处理xlsx文件出现科学计数法数据
源数据长这样

作者查阅了网上资料使用converters或dtype
dtype用于指定列的数据类型converter用于应用自定义转换函数- 转换器优先级更高,因为它可以执行更复杂的操作
- 如果同时指定,Pandas 会忽略
dtype以避免冲突
def pre_script_func(remote_file, transform_file_path, dest_tb_columns, transform_file_seperator):
file_tb = pd.read_excel(remote_file,
sheet_name=2,
engine="openpyxl",
header=0,
names=dest_tb_columns,
usecols=[_ for _ in range(len(dest_tb_columns))],
converters={_: str for _ in dest_tb_columns},
# dtype={i: str for i in range(len(dest_tb_columns))}
)
file_tb.to_json(transform_file_path, orient="records", lines=True, force_ascii=False)
return transform_file_path
但返回的数据且不是我想要的数据,如果你的数据返回正常那么恭喜你可以不用往下看了。

那么数据为啥没有转化成功呢?
好吧,不卖关子了,其实是因为源数据有可能有多种类型的数据同时存在,那么我们使用apply方法来进行特殊处理吧
def pre_script_func(remote_file, transform_file_path, dest_tb_columns, transform_file_seperator):
file_tb = pd.read_excel(remote_file,
sheet_name=2,
engine="openpyxl",
header=0,
names=dest_tb_columns,
usecols=[_ for _ in range(len(dest_tb_columns))],
converters={_: str for _ in dest_tb_columns},
# dtype={i: str for i in range(len(dest_tb_columns))}
)
def convert_value(value):
"""处理混合类型值"""
if isinstance(value, float):
# 处理浮点数(科学计数法)
return f"{value:.0f}" # 转换为整数字符串
elif isinstance(value, int):
# 处理整数
return str(value)
elif isinstance(value, str):
# 处理字符串
if 'e+' in value or 'e-' in value:
# 处理科学计数法字符串
try:
return f"{float(value):.0f}"
except:
return value
else:
return value
else:
return str(value)
file_tb[['col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7']] = file_tb[['col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7']].applymap(convert_value)
#
# # 替换DataFrame中的空字符串为Nan
# # file_tb.replace("", np.nan, inplace=True)
file_tb.to_json(transform_file_path, orient="records", lines=True, force_ascii=False)
return transform_file_path
这回好像数据都是正常的了

别高兴太早,我们来看看源数据为243120000003649000,返回的数据却是243120000003648992;什么原因呢?精度损失了?

那是因为使用 f"{float(value):.0f}" 确实会导致大整数精度损失,因为 Python 的浮点数(IEEE 754 双精度)只能精确表示最多约 15-17 位的整数。对于超过这个位数的整数(如 243120000003649000),转换为浮点数再转回整数会导致精度损失。
精度损失的原因
-
浮点数精度限制:
- IEEE 754 双精度浮点数有 53 位尾数
- 只能精确表示绝对值小于 2⁵³ (约 9e15) 的整数
- 243120000003649000 (18位) > 9e15 (16位),超出精确表示范围
-
转换过程:
original = 243120000003649000 as_float = float(original) # 变为 243120000003649000.0 (但实际存储为近似值) back_to_int = int(as_float) # 变为 243120000003648992 (精度损失)
完整解决方案:避免浮点数转换,代码修改后
def pre_script_func(remote_file, transform_file_path, dest_tb_columns, transform_file_seperator):
file_tb = pd.read_excel(remote_file,
sheet_name=2,
engine="openpyxl",
header=0,
names=dest_tb_columns,
usecols=[_ for _ in range(len(dest_tb_columns))],
converters={_: str for _ in dest_tb_columns},
# dtype={i: str for i in range(len(dest_tb_columns))}
)
def convert_value(value):
"""处理混合类型值,避免精度损失"""
# 检查是否为 NaN
if isinstance(value, float) and math.isnan(value):
return "" # 或者返回 None 或其他占位符
if isinstance(value, float):
# 对于大浮点数,直接格式化为字符串
if abs(value) > 1e15:
# 使用字符串格式化避免浮点转换
return format(value, '.0f')
# 对于小浮点数,检查是否为整数
if value.is_integer():
return str(int(value))
return str(value) # 保留小数部分
elif isinstance(value, int):
return str(value)
elif isinstance(value, str):
# 使用正则表达式精确匹配科学计数法
sci_match = re.match(r'^([-+]?\d*\.?\d+)[eE]([-+]?\d+)$', value)
if sci_match:
# 直接处理科学计数法字符串
try:
# 提取基数和指数
base = sci_match.group(1)
exp = int(sci_match.group(2))
# 处理底数中的小数点
if '.' in base:
integer_part, fractional_part = base.split('.')
else:
integer_part = base
fractional_part = ''
# 计算需要移动的小数点位数
move = exp - len(fractional_part) if exp >= 0 else exp
if move > 0:
# 正指数:在末尾补零
return integer_part + fractional_part + '0' * move
elif move < 0:
# 负指数:在整数部分插入小数点
pos = len(integer_part) + move
if pos > 0:
return integer_part[:pos] + '.' + integer_part[pos:] + fractional_part
else:
return '0.' + '0' * (-pos) + integer_part + fractional_part
else:
return integer_part + fractional_part
except Exception as e:
print(f"处理科学计数法时出错: {e}, 值: {value}")
return value
else:
return value
else:
return str(value)
file_tb[['col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7']] = file_tb[['col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7']].applymap(convert_value)
#
# # 替换DataFrame中的空字符串为Nan
# # file_tb.replace("", np.nan, inplace=True)
file_tb.to_json(transform_file_path, orient="records", lines=True, force_ascii=False)
return transform_file_path
数据正常了

7、pandas处理所有列非NaN值的数据类型转化为字符串
使用 mask 条件替换
通过布尔掩码选择性转换:
file_tb = file_tb.mask(file_tb.notna(), file_tb.astype(str))
逻辑:
其他场景
file_tb.notna():生成布尔掩码(True为非NaN位置)。.mask(cond, other):对cond=True的位置替换为other(此处为字符串化后的值)。
| 方法 | 适用场景 | 代码示例 |
|---|---|---|
applymap | 小规模数据,逐元素控制 | df.applymap(lambda x: str(x) if pd.notna(x) else x) |
| 列级循环 | 中等规模数据,平衡性能与可读性 | for col in df: df[col] = df[col].apply(lambda x: str(x) if pd.notna(x) else x) |
mask | 向量化操作,性能最优 | df.mask(df.notna(), df.astype(str)) |
本文介绍了如何使用Pandas对DataFrame进行数据清洗,包括替换特殊符号、清除空格、去重操作,并关注了CSV文件中的换行符处理以及如何在Hive中正确表示NULL值。
296






