pandas读取json,时间被自动添加了当前日期,真是大坑

本文介绍如何使用Python的pandas库处理从数据库获取的SQL查询结果,并将其转换为JSON格式。此外,还详细说明了如何读取JSON数据并进行日期格式的转换,以适应不同的显示需求。
process_reslut = pd.read_sql_query(process_sql, gjcsdb, params=params)
json_process=process_reslut.to_json(orient="records", force_ascii=False)
after_reslut = pd.read_json(json_process)

 

为了处理只能再次改为

after_reslut = pd.read_json(json_process,dtype=True)
after_reslut['create_date_time']=after_reslut['create_date_time'].apply(lambda x: x.strftime("%H:%M:%S"))

 

msg : "Python script failed with exit code: 1# -*- coding: utf-8 -*- """ 协同过滤推荐系统脚本(基于物品的协同过滤) 功能:读取用户-商品行为数据,计算商品相似度,为指定用户生成推荐列表 输入:通过命令行传入用户ID,从JSON文件读取用户购买行为数据 输出:将推荐的商品ID列表写入输出JSON文件 """ import sys # 用于获取命令行参数 import json # 用于读写 JSON 格式的数据文件 import pandas as pd # 数据处理库,用于构建矩阵和分析 from sklearn.metrics.pairwise import cosine_similarity # 计算余弦相似度 def main(): """ 主函数:执行完整的推荐流程 步骤: 1. 获取目标用户ID 2. 读取用户-商品交互数据 3. 构建用户-商品评分矩阵 4. 计算商品之间的相似度(Item-Based) 5. 为目标用户生成推荐商品列表 6. 将结果写入输出文件 """ # ========== 第一步:获取命令行传入的用户ID ========== if len(sys.argv) < 2: print("错误:未提供用户ID") print("用法示例:python collaborative_filtering.py <user_id>") sys.exit(1) # 参数不足则退出程序 try: target_user_id = int(sys.argv[1]) # 获取第一个命令行参数作为用户ID except ValueError: print("错误:用户ID必须是一个整数") sys.exit(1) # ========== 第二步:从JSON文件加载用户-商品行为数据 ========== input_file_path = 'src/main/resources/scripts/input.json' # 输入文件路径(由Spring Boot生成) try: with open(input_file_path, 'r', encoding='utf-8') as f: data = json.load(f) # 加载JSON数据为Python列表 except FileNotFoundError: print(f"错误:找不到输入文件 {input_file_path}") sys.exit(1) except json.JSONDecodeError as e: print(f"错误:JSON解析失败:{e}") sys.exit(1) # 将数据转换为 Pandas DataFrame df = pd.DataFrame(data) # 如果没有数据,直接返回空推荐 if df.empty: print("警告:输入数据为空,无法进行推荐") with open('src/main/resources/scripts/output.json', 'w', encoding='utf-8') as f: json.dump([], f) # 输出空列表 return # ========== 第三步:构建用户-商品交互矩阵 ========== # 行:用户(userId),列:商品(productId),值:购买次数(count) # fillna(0):将缺失值(未购买)补为0 user_item_matrix = df.pivot(index='userId', columns='productId', values='count').fillna(0) print(f"用户-商品矩阵形状:{user_item_matrix.shape}") # ========== 第四步:计算商品之间的相似度(Item-Based 协同过滤)========== # 使用余弦相似度衡量两个商品被相同用户购买的模式是否相似 # .T 表示转置:把商品变为行,用户变为列,便于计算商品间相似性 item_similarity = cosine_similarity(user_item_matrix.T) # 得到相似度矩阵(二维数组) # 将相似度数组转为DataFrame,方便按商品ID索引 item_sim_df = pd.DataFrame( item_similarity, index=user_item_matrix.columns, # 商品ID作为行索引 columns=user_item_matrix.columns # 商品ID作为列索引 ) # ========== 第五步:为指定用户生成推荐列表 ========== if target_user_id not in user_item_matrix.index: # 用户不存在于训练数据中(新用户),无法推荐 print(f"警告:用户 {target_user_id} 无历史行为数据,返回空推荐(冷启动)") recommendations = [] else: # 获取该用户的购买记录 user_ratings = user_item_matrix.loc[target_user_id] # Series: productId -> count # 找出该用户已购买的商品 bought_items = user_ratings[user_ratings > 0].index # 已购商品ID列表 # 初始化一个Series用于累计每个商品的推荐得分 scores = pd.Series(0, index=item_sim_df.index) # 初始全为0 # 对每一个用户买过的商品,将其相似商品的得分加权累加 for item in bought_items: # item_sim_df[item]: 当前商品与其他所有商品的相似度 # user_ratings[item]: 用户对该商品的“兴趣强度”(可用购买次数表示) scores += item_sim_df[item] * user_ratings[item] # 过滤掉用户已经买过的商品 candidate_scores = scores.drop(bought_items, errors='ignore') # 按得分降序排列,取前5个最相似且未购买的商品 top_recommendations = candidate_scores.sort_values(ascending=False).head(5) # 提取商品ID并转为整数列表 rec_list = top_recommendations.index.tolist() recommendations = [int(pid) for pid in rec_list] print(f"为用户 {target_user_id} 推荐商品: {recommendations}") # ========== 第六步:将推荐结果写入输出文件 ========== output_file_path = 'resources/temp/output.json' try: with open(output_file_path, 'w', encoding='utf-8') as f: json.dump(recommendations, f, ensure_ascii=False, indent=2) # 格式化保存 print("推荐结果已成功写入输出文件") except Exception as e: print(f"错误:无法写入输出文件 {output_file_path}: {e}") sys.exit(1) # 程序入口点 if __name__ == "__main__": """ 当脚本被直接运行时(而非被导入),执行 main() 函数 示例运行命令: python collaborative_filtering.py 123 """ main() package com.shop.jieyou.controller; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.shop.jieyou.common.Result; import com.shop.jieyou.entity.UserItem; import com.shop.jieyou.service.PythonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 花卉相关接口控制器 * 提供三大功能: * 1. 获取中国十大名花数据(来自爬虫或缓存) * 2. 手动刷新花卉数据(强制重新爬取) * 3. 基于用户行为的花卉推荐(调用Python协同过滤脚本) */ @RestController @CrossOrigin(origins = "*") // 允许所有域访问,用于前端开发调试(生产环境建议限制域名) @RequestMapping("/api") public class FlowerController { @Autowired private PythonService pythonService; // 注入业务服务层,处理数据获取与推荐逻辑 /** * 接口:GET /api/flowers * 功能:获取“中国十大名花”数据列表 * 数据来源:可能来自数据库、Redis 缓存 或 调用 Python 爬虫脚本 * * @return Result<List<Map<String, Object>>> 返回包含花卉信息的成功响应 */ @GetMapping("/flowers") public Result<List<Map<String, Object>>> getTopTenFlowers() { try { // 调用服务层获取花卉数据(内部可能带缓存机制) List<Map<String, Object>> flowers = pythonService.getFlowers(); return Result.success(flowers); // 成功返回数据 } catch (Exception e) { // 捕获异常并统一返回错误码和消息,避免暴露堆栈给前端 return Result.error("500", "获取花卉数据失败:" + e.getMessage()); } } /** * 接口:POST /api/flowers/refresh * 功能:强制刷新花卉数据缓存,触发重新爬取 * 使用场景:管理员手动更新数据时调用 * * @return Result<Map<String, Object>> 返回刷新结果信息 */ @PostMapping("/flowers/refresh") public Result<Map<String, Object>> refreshData() { try { // TODO: 如果实现了 clearCache 方法,请取消注释并调用 // pythonService.clearCache(); // 清除旧缓存,下次 getFlowers 将重新爬取 // 重新获取最新数据(假设此时会触发爬虫) List<Map<String, Object>> flowers = pythonService.getFlowers(); // 构造返回信息 Map<String, Object> data = new HashMap<>(); data.put("message", "数据已刷新"); data.put("count", flowers.size()); return Result.success(data); } catch (Exception e) { return Result.error("500", "刷新失败:" + e.getMessage()); } } // ========== 推荐系统相关常量定义 ========== /** * 输入文件路径:Java 将用户-商品行为数据写入此 JSON 文件供 Python 脚本读取 * 注意:src/main/resources 是编译后打包进 jar 的资源目录,不适合运行时写入! * 建议改为外部路径如 "./data/input.json" */ private static final String INPUT_PATH = "src/main/resources/scripts/input.json"; /** * 输出文件路径:Python 脚本将推荐结果写入此文件,Java 再读取返回给前端 */ private static final String OUTPUT_PATH = "src/main/resources/scripts/output.json"; /** * Python 协同过滤脚本路径 * 注意:resources 目录下的 .py 文件在打包后无法直接作为可执行脚本运行 * 更佳做法是将脚本放在项目外部或使用 ProcessBuilder 启动独立服务 */ private static final String PYTHON_SCRIPT = "src/main/resources/scripts/collaborative.py"; /** * 接口:GET /api/recommend?userId=123 * 功能:为指定用户生成个性化花卉推荐列表 * 实现方式:Java 查询数据库 → 写入 JSON 文件 → 调用 Python 脚本计算 → 读取结果返回 * * @param userId 用户ID,必填参数 * @return Result<JsonNode> 推荐的商品ID数组(如 [101, 105, 108]) */ @GetMapping("/recommend") public Result recommendFlowers(@RequestParam("userId") Long userId) { try { // 1. 从数据库查询用户-商品交互记录(例如购买、浏览次数) List<UserItem> matrix = pythonService.getUserItemMatrix(); // 2. 使用 Jackson 将数据序列化为 JSON 并写入文件 ObjectMapper mapper = new ObjectMapper(); File inputFile = new File(INPUT_PATH); // ✅ 增强健壮性:确保父目录存在 if (!inputFile.getParentFile().exists()) { inputFile.getParentFile().mkdirs(); // 自动创建 scripts 目录 } mapper.writeValue(inputFile, matrix); // 3. 调用 Python 协同过滤脚本 ProcessBuilder pb = new ProcessBuilder("python", PYTHON_SCRIPT, String.valueOf(userId)); pb.redirectErrorStream(true); // 合并标准输出和错误流,便于捕获日志 Process process = pb.start(); // 等待脚本执行完成 int exitCode = process.waitFor(); if (exitCode != 0) { // Python 脚本执行失败 return Result.error("error", "Python script failed with exit code: " + exitCode); } // 4. 读取 Python 输出的推荐结果 File outputFile = new File(OUTPUT_PATH); if (!outputFile.exists()) { return Result.error("error", "Python script did not generate output file."); } JsonNode result = mapper.readTree(outputFile); // 成功返回推荐结果 return Result.success(result); } catch (Exception e) { // 统一异常处理,返回标准化错误格式 e.printStackTrace(); // 开发期打印堆栈,生产环境应使用日志框架 return Result.error("500", "推荐生成失败:" + e.getMessage()); } } }
最新发布
10-17
<think>我们正在使用Pandas读取JSON文件。根据引用[1],Pandas提供了从JSON字符串读取数据的函数pd.read_json()。但注意,我们也可以直接从JSON文件中读取。 实际上,pd.read_json()可以接受多种形式的输入:字符串、路径对象(文件路径)或文件句柄。 因此,要读取一个JSON文件,我们可以使用: df = pd.read_json('文件路径.json') 但是,需要注意的是,JSON文件可能有不同的格式(如每行一个记录、嵌套的JSON等)。Pandas的read_json函数有一些参数可以处理不同的结构,例如: - orient: 指示JSON字符串的格式,可选参数如'records'、'split'、'index'等,具体取决于JSON的结构。 - lines: 如果JSON文件是每行一个JSON对象(即JSON lines格式),则设置lines=True。 例如,对于JSON lines格式(每行一个JSON对象)的文件,我们可以这样读取: df = pd.read_json('data.json', lines=True) 对于普通的JSON文件,可能不需要lines参数,但需要根据JSON的结构设置orient参数。 另外,如果JSON文件是嵌套结构,可能需要先将其展平。Pandas读取后,嵌套的JSON可能会被读成DataFrame中的字典或列表列,这时我们可以使用json_normalize函数(来自pandas.io.json)来处理嵌套结构。 但是,根据用户问题,我们只需要读取JSON文件。因此,基本的读取方法就是使用pd.read_json()并传入文件路径。 步骤: 1. 导入pandas库 2. 使用pd.read_json()函数,并指定文件路径 3. 可选:根据JSON结构设置orient、lines等参数 示例代码: import pandas as pd df = pd.read_json('example.json') 如果遇到嵌套结构,可能需要进一步处理。但用户没有提到嵌套,所以先给出基本方法。 注意:如果JSON文件很大,可能需要考虑使用chunksize参数进行分块读取,但read_json不支持chunksize。对于大文件,可以考虑使用ijson等库逐行解析,或者如果每行一个记录(JSON lines)则可以使用lines=True并配合chunksize(实际上read_json没有chunksize,但read_json支持迭代器模式?)。查阅文档:read_json函数没有chunksize参数,但我们可以使用分块读取的方法是:如果文件是JSON lines格式(每行一个JSON对象),我们可以逐块读取文件内容,然后对每块使用pd.read_json()。但这不是直接支持的。 因此,我们主要回答如何读取一般的JSON文件。 另外,引用[3]中提到了从CSV读取,但用户需要的是JSON,所以我们参考引用[1]中提到的pd.read_json()。 总结:使用pd.read_json()函数,根据文件结构设置参数。 下面给出一个示例代码:</think>### 使用Pandas读取JSON文件的方法 在Python中使用Pandas读取JSON文件非常简单,主要通过`pd.read_json()`函数实现。以下是详细步骤: #### 1. **基本读取方法** ```python import pandas as pd # 从JSON文件直接读取数据 df = pd.read_json('data.json') # 显示前5行数据 print(df.head()) ``` - ⚠️ 要求JSON文件是标准格式(如:字典列表、嵌套结构需符合Pandas解析规则) - 支持本地文件路径或URL(如`pd.read_json('https://example.com/data.json')`) #### 2. **处理不同JSON格式** 根据JSON结构可能需要指定`orient`参数: ```python # 处理行格式JSON(每行一个JSON对象) df = pd.read_json('data.json', lines=True) # 适用于JSON Lines格式 # 处理嵌套结构(orient参数指定数据结构) df = pd.read_json('nested.json', orient='records') # 其他选项:'split','index','columns' ``` #### 3. **数据类型转换** ```python # 自动转换日期列 df = pd.read_json('data.json', convert_dates=['birthday']) # 保留原始数据类型 df = pd.read_json('data.json', dtype={'user_id': str}) ``` #### 4. **从JSON字符串读取** ```python json_string = '{"name":"John", "age":30, "city":"New York"}' df = pd.read_json(json_string, orient='index').T # 转置为DataFrame ``` #### 5. **处理复杂嵌套JSON** 对于多层嵌套数据,建议先用Python解析再转换: ```python import json with open('complex.json') as f: data = json.load(f) # 展平嵌套结构 df = pd.json_normalize(data, 'users', ['group_id']) ``` > **关键参数说明**: > - `orient`:指定JSON结构(默认'infer'自动检测) > - `lines`:处理每行一个JSON对象的文件(如日志数据) > - `convert_dates`:自动转换日期字段 > - `dtype`:指定列数据类型 > - `encoding`:设置文件编码(如'utf-8') #### 常见错误处理: 1. **JSON解析错误** → 验证文件有效性(可使用[jsonlint.com](https://jsonlint.com/)) 2. **编码问题** → 添加`encoding='utf-8-sig'`参数 3. **内存不足** → 分块读取:`chunksize=1000` [^1]: Pandas支持从多种文件格式中读取数据,如CSV、Excel、SQL数据库等 [^2]: pandas入门。初始化一个dataFrame,可以read_csv从csv文件获取 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值