import os import pandas as pd # 设置目录路径 input_dir = r'E:\hulin' output_file = r'E:\hulin\merged_filtered.csv' # 定义需要排除的文件名(如许可证、README等) excluded_files = { 'LICENSE.txt', 'README.txt', 'API_CHANGES.txt', 'umath-validation-set-README.txt', 'entry_points.txt', 'vendor.txt', 'AUTHORS.txt', 'top_level.txt' } # 定义必要的列名(统一转换为小写并去除空格,以便进行匹配) required_columns = { '对手方id', '交易金额(分)', '交易用途类型', '用户银行卡号', '对手侧账户名称', '用户侧账号名称', '借贷类型' } # 初始化一个空的列表,用于存储每个文件处理后的DataFrame df_list = [] # 遍历目录中的所有TXT文件 for root, dirs, files in os.walk(input_dir): for filename in files: if filename.lower().endswith('.txt') and filename not in excluded_files: file_path = os.path.join(root, filename) try: # 尝试读取TXT文件,假设使用制表符分隔 df = pd.read_csv(file_path, sep='\t', encoding='utf-8', low_memory=False) except: # 如果读取失败,尝试其他编码 try: df = pd.read_csv(file_path, sep='\t', encoding='gbk', low_memory=False) except Exception as e: print(f"无法读取文件 {file_path}: {e}") continue # 标准化列名:去除前后空格并转换为小写 df.columns = df.columns.str.strip().str.lower() # 确保必要的列存在 if not required_columns.issubset(df.columns): missing_cols = required_columns - set(df.columns) print(f"文件 {filename} 缺少必要的列: {missing_cols},跳过处理。") continue # 数据清洗:去除“用户银行卡号”中的空格和特殊字符 df['用户银行卡号'] = df['用户银行卡号'].astype(str).str.replace(r'\s+|[^0-9Xx]', '', regex=True) # 筛选“交易用途类型”为“转账” df = df[df['交易用途类型'] == '转账'] # 筛选“交易金额(分)”大于9900 df = df[df['交易金额(分)'] > 9900] # 统计“对手方ID”出现次数,并筛选出出现超过2次的ID id_counts = df['对手方id'].value_counts() valid_ids = id_counts[id_counts > 2].index df = df[df['对手方id'].isin(valid_ids)] # 新增条件:排除“对手侧账户名称”和“用户侧账号名称”相同的记录 df = df[df['对手侧账户名称'] != df['用户侧账号名称']] # 获取上两级文件夹名称 relative_path = os.path.relpath(root, input_dir) folder_name = os.path.join(*relative_path.split(os.sep)[-2:]) if relative_path != '.' else '' # 添加新列“文件夹路径”到首列 df.insert(0, '文件夹路径', folder_name) # 将“交易金额(分)”转换为元,并根据“借贷类型”调整正负 # 使用向量化操作替代 apply df['交易金额(元)'] = df['交易金额(分)'] / 100 # 先转换为元 df.loc[df['借贷类型'] == '出', '交易金额(元)'] *= -1 # 如果“借贷类型”为“出”,则转为负数 # 插入“交易金额(元)”列到“交易金额(分)”右侧 # 获取“交易金额(分)”的列位置索引 amount_col_idx = df.columns.get_loc('交易金额(分)') # 创建新的列顺序 new_order = list(df.columns[:amount_col_idx + 1]) + ['交易金额(元)'] + list(df.columns[amount_col_idx + 1:]) df = df[new_order] # 确保“交易金额(元)”为数值型(已经通过上述操作确保) # 可选:如果需要,可以再次确认 # df['交易金额(元)'] = pd.to_numeric(df['交易金额(元)'], errors='coerce') # 将处理后的DataFrame添加到列表中 df_list.append(df) # 在合并之前,移除所有 DataFrame 中全为空的列 if df_list: # 移除所有列均为NA的列 df_list_clean = [] for df in df_list: df_clean = df.dropna(axis=1, how='all') df_list_clean.append(df_clean) # 合并所有DataFrame merged_df = pd.concat(df_list_clean, ignore_index=True) # 确保“交易金额(元)”列为数值型 merged_df['交易金额(元)'] = pd.to_numeric(merged_df['交易金额(元)'], errors='coerce') # 可选:根据需要选择是否去重 # merged_df = merged_df.drop_duplicates() # 保存为新的CSV文件,确保编码正确 merged_df.to_csv(output_file, index=False, encoding='utf-8-sig') print(f"所有符合条件的数据已成功合并并保存到 {output_file}") else: print("没有符合条件的数据需要保存。") 出现”借贷类型“列下是”出“但是”交易金额(分)“列没有转成负值的形况
时间: 2025-03-11 13:08:45 浏览: 40
从您的描述来看,您遇到的问题是在将“借贷类型”为“出”的记录中的“交易金额(分)”转成负值的过程中出现了异常情况。按照正常的逻辑流程,“借贷类型”为“出”的记录对应的“交易金额(元)”应该转换为负数。
我们可以检查一下可能导致此问题的原因以及如何修正这个问题:
### 检查点及解决方案
1. **确保数据一致性**
在对DataFrame进行各种过滤和修改之后,可能存在某些情况下`'借贷类型'`列的数据不是预期的字符串(例如包含了空格或其他非字母字符)。为了保证判断条件的有效性,在应用任何变换前应标准化该字段内容:
```python
df['借贷类型'] = df['借贷类型'].str.strip() # 去除两端空白字符
```
2. **检查转换逻辑的位置**
确认在设置`'交易金额(元)'`一栏之前就已经完成了对于原始货币数值(`'交易金额(分)'`)的所有必要筛选和清理工作,并且这个步骤确实发生在生成最终输出之前的适当时间点上。
3. **验证是否有遗漏更新的情况**
当我们创建了新列并且基于现有列进行了计算后,有时可能会忘记及时反映最新的状态变更。这里的关键在于理解Python中Pandas库的工作机制——即每一步都是返回一个新的DataFrame实例而不是直接改变原对象的状态,除非明确指定了就地(in-place)操作。
4. **简化调试过程**
您可以尝试通过打印中间结果的方式来追踪哪里出了差错,比如在这段代码里加入一些print语句查看各个阶段的数据状况:
```python
# 查看当前df的具体内容以确定是否存在未正常转换的情况
print("正在处理:", filename)
print(df[['交易金额(分)', '借贷类型']].head())
```
5. **优化赋值逻辑**
考虑到性能因素,尽量避免多次访问或更改DataFrame中的单个元素;而应当尽可能利用向量化的表达式来进行批量运算。这不仅提高了效率而且减少了错误发生的可能性。目前的做法看起来已经是相当合理的向量化实现了,但仍需注意细节上的精确度。
最后建议做一次完整的测试运行,同时启用详细的日志输出功能帮助定位潜在的问题源。如果还有疑问的话,请提供更多的上下文信息或者具体的样例数据片段,这样可以帮助更准确地诊断问题所在。
阅读全文