data_cleaning.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # time: 2023/10/11 11:00
  4. # file: data_cleaning.py
  5. # author: David
  6. # company: shenyang JY
  7. import numpy as np
  8. np.random.seed(42)
  9. def cleaning(df, name, logger, cols=None, dup=True, col_time='dateTime'):
  10. logger.info("开始清洗:{}……".format(name))
  11. data = df.copy()
  12. data = data_column_cleaning(data, logger)
  13. if dup:
  14. data = rm_duplicated(data, logger, col_time)
  15. if cols is not None:
  16. data = key_field_row_cleaning(data, cols, logger)
  17. return data
  18. def data_column_cleaning(data, logger, clean_value=[-99.0, -99]):
  19. """
  20. 列的清洗
  21. :param data:
  22. :param logger:
  23. :param clean_value:
  24. :return:
  25. """
  26. data1 = data.copy()
  27. cols_pre = data.columns.to_list()
  28. for val in clean_value:
  29. data1 = data1.replace(val, np.nan)
  30. # nan 列超过80% 删除
  31. data1 = data1.dropna(axis=1, thresh=len(data) * 0.8)
  32. # 删除取值全部相同的列
  33. data1 = data1.loc[:, (data1 != data1.iloc[0]).any()]
  34. data = data[data1.columns.tolist()]
  35. cols_late = data.columns.tolist()
  36. if len(cols_pre) > len(cols_late):
  37. logger.info("列清洗:清洗的列有:{}".format(set(cols_pre) - set(cols_late)))
  38. return data
  39. def key_field_row_cleaning(data, cols, logger):
  40. """
  41. 行的重要字段清洗: 过滤含有- 99的数字,过滤空值
  42. :param data:
  43. :param cols: 指定的字段列表
  44. :param logger:
  45. :return:
  46. """
  47. rows_pre = len(data)
  48. nan_cols = []
  49. for col in cols:
  50. begin = len(data)
  51. if col in data.columns.tolist():
  52. # data = data[~((data.loc[:, col] < 0) & (data.loc[:, col].astype(str).str.contains('99')))]
  53. data = data[~(data[col] == -99)]
  54. data = data[~data.loc[:, col].isnull()]
  55. end = len(data)
  56. if end - begin > 0:
  57. nan_cols.append(col)
  58. rows_late = len(data)
  59. if rows_pre - rows_late > 0:
  60. logger.info("行清洗:清洗的行数有:{},缺失的列有:{}".format(rows_pre-rows_late, ', '.join(nan_cols)))
  61. return data
  62. def rm_duplicated(data, logger, col_time='dateTime'):
  63. """
  64. 按照时间去重
  65. :param data:
  66. :param logger:
  67. :return:
  68. """
  69. # 按照时间去重
  70. rows_pre = len(data)
  71. data = data.drop_duplicates(subset=col_time)
  72. rows_late = len(data)
  73. if rows_pre - rows_late > 0:
  74. logger.info("时间去重的行数有:{}".format(rows_pre - rows_late))
  75. return data