parse_file.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. 解析振动数据文件
  5. 从FDFS下载文件并解析数据
  6. """
  7. import zlib
  8. import json
  9. import sys
  10. import os
  11. # 设置控制台输出编码(Windows需要,Linux默认UTF-8)
  12. if sys.platform == 'win32':
  13. try:
  14. os.system('chcp 65001 >nul 2>&1')
  15. except:
  16. pass
  17. else:
  18. # Linux环境下设置UTF-8编码
  19. import locale
  20. try:
  21. locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
  22. except:
  23. try:
  24. locale.setlocale(locale.LC_ALL, 'C.UTF-8')
  25. except:
  26. pass
  27. def parse_file_data(file_name, use_fdfs=False, fdfs_client=None):
  28. """
  29. 解析文件数据
  30. 参数:
  31. file_name: 文件路径(FDFS路径或本地路径)
  32. use_fdfs: 是否使用FDFS客户端(如果为True,需要提供fdfs_client)
  33. fdfs_client: FDFS客户端对象(可选)
  34. 返回:
  35. 解析后的数据(字典或列表)
  36. """
  37. try:
  38. # 1.1 从 FDFS 下载文件数据,先把文件名转成 UTF-8 编码的二进制串
  39. if use_fdfs and fdfs_client:
  40. # 使用FDFS客户端下载
  41. data = fdfs_client.download_bytes(bytes(file_name, encoding="utf8"))
  42. else:
  43. # 如果没有FDFS客户端,尝试从本地文件系统读取
  44. # 将FDFS路径转换为本地路径
  45. if file_name.startswith('group1/M00/'):
  46. local_path = file_name.replace('group1/M00/', '/home/soft/data/fdfs/storage/data/', 1)
  47. elif file_name.startswith('group1/M00'):
  48. local_path = file_name.replace('group1/M00', '/home/soft/data/fdfs/storage/data', 1)
  49. else:
  50. local_path = file_name
  51. # 从本地文件系统读取
  52. with open(local_path, 'rb') as f:
  53. data = f.read()
  54. # 1.2 检查下载的二进制数据开头是否是 {(JSON 格式的标志)
  55. if data[0:1] == b'{':
  56. # 如果是 JSON 二进制串,直接解码成字符串
  57. data = data.decode()
  58. else:
  59. # 如果不是 JSON 开头,说明数据是压缩的,先解压
  60. ss = zlib.decompress(data).decode()
  61. # 修正格式:单引号改双引号(JSON 要求双引号)、nan 改成 0(避免 JSON 解析报错)
  62. ss = ss.replace('\'', '"').replace("nan", "0")
  63. # 把修正后的字符串解析成 JSON 格式的 Python 数据(字典/列表)
  64. data = json.loads(ss)
  65. return data
  66. except FileNotFoundError as e:
  67. print(f"[错误] 文件未找到: {e}")
  68. return None
  69. except zlib.error as e:
  70. print(f"[错误] 解压缩失败: {e}")
  71. return None
  72. except json.JSONDecodeError as e:
  73. print(f"[错误] JSON解析失败: {e}")
  74. return None
  75. except Exception as e:
  76. print(f"[错误] 解析文件时发生错误: {e}")
  77. import traceback
  78. traceback.print_exc()
  79. return None
  80. def calculate_asymmetry(data):
  81. """
  82. 计算不对称性
  83. 从data中提取raw_y数组,然后计算不对称性
  84. 返回 (abs_正, abs_负)
  85. """
  86. try:
  87. # 如果data是字典,提取raw_y字段
  88. if isinstance(data, dict):
  89. if 'raw_y' not in data:
  90. return None, None
  91. values_list = data['raw_y']
  92. elif isinstance(data, list):
  93. # 如果是列表,直接使用(兼容旧代码)
  94. values_list = data
  95. else:
  96. return None, None
  97. # 确保values_list是列表
  98. if not isinstance(values_list, list):
  99. return None, None
  100. # 转换为数值列表
  101. values = []
  102. for v in values_list:
  103. try:
  104. val = float(v)
  105. values.append(val)
  106. except (ValueError, TypeError):
  107. continue
  108. if len(values) == 0:
  109. return None, None
  110. # 分离正半轴和负半轴的值
  111. positive_values = [v for v in values if v > 0]
  112. negative_values = [abs(v) for v in values if v < 0] # 负半轴取绝对值
  113. # 计算和
  114. sum_positive = sum(positive_values)
  115. sum_negative = sum(negative_values)
  116. # 计算不对称性
  117. if sum_positive > 0:
  118. abs_positive = abs((sum_positive - sum_negative) / sum_positive)
  119. else:
  120. abs_positive = None
  121. if sum_negative > 0:
  122. abs_negative = abs((sum_positive - sum_negative) / sum_negative)
  123. else:
  124. abs_negative = None
  125. return abs_positive, abs_negative
  126. except Exception as e:
  127. print(f"[错误] 计算不对称性时发生错误: {e}")
  128. return None, None
  129. def main():
  130. """主函数"""
  131. # 从命令行参数获取文件路径
  132. if len(sys.argv) < 2:
  133. print("[错误] 请提供文件路径作为参数")
  134. print("使用方法: python parse_file.py <file_name>")
  135. print("示例: python parse_file.py group1/M00/4C/AD/wKgUZWlQzpKAcUtmAA03b1suhI44618492")
  136. sys.exit(1)
  137. file_name = sys.argv[1]
  138. print("=" * 60)
  139. print("文件解析工具")
  140. print("=" * 60)
  141. print(f"文件路径: {file_name}")
  142. print("-" * 60)
  143. # 解析文件
  144. print("正在解析文件...")
  145. data = parse_file_data(file_name, use_fdfs=False)
  146. if data is not None:
  147. print("\n[成功] 文件解析成功!")
  148. print("=" * 60)
  149. print("解析后的数据:")
  150. print("=" * 60)
  151. # 打印数据
  152. # 如果是字典或列表,使用json.dumps格式化输出
  153. if isinstance(data, (dict, list)):
  154. print(json.dumps(data, indent=2, ensure_ascii=False))
  155. else:
  156. print(data)
  157. print("=" * 60)
  158. # 打印数据类型和基本信息
  159. print(f"\n数据类型: {type(data).__name__}")
  160. if isinstance(data, dict):
  161. print(f"字典键数量: {len(data)}")
  162. print(f"字典键: {list(data.keys())}")
  163. elif isinstance(data, list):
  164. print(f"列表长度: {len(data)}")
  165. if len(data) > 0:
  166. print(f"第一个元素类型: {type(data[0]).__name__}")
  167. if isinstance(data[0], (dict, list)):
  168. print(f"第一个元素: {json.dumps(data[0], indent=2, ensure_ascii=False)[:200]}...")
  169. # 计算不对称性
  170. print("\n" + "=" * 60)
  171. print("不对称性计算:")
  172. print("=" * 60)
  173. abs_positive, abs_negative = calculate_asymmetry(data)
  174. if abs_positive is not None and abs_negative is not None:
  175. print(f"abs正: {abs_positive:.10f}")
  176. print(f"abs负: {abs_negative:.10f}")
  177. else:
  178. print("[警告] 无法计算不对称性(数据中可能缺少raw_y字段或raw_y为空)")
  179. if isinstance(data, dict) and 'raw_y' in data:
  180. raw_y = data['raw_y']
  181. print(f"raw_y类型: {type(raw_y).__name__}")
  182. if isinstance(raw_y, list):
  183. print(f"raw_y长度: {len(raw_y)}")
  184. else:
  185. print("\n[失败] 文件解析失败!")
  186. sys.exit(1)
  187. if __name__ == "__main__":
  188. main()