手动修改数据的良好做法

数据挖掘 数据清理
2021-10-01 16:50:28

通常情况下,我使用的数据不是 100% 干净的。即使它相当干净,仍然有部分需要修复。

当一小部分数据需要它时,我会编写一个脚本并将其合并到数据处理中。

但是如果只需要修复几个条目(例如拼写错误的城市或邮政编码)怎么办?让我们关注“小数据”,例如 CSV 文件或关系数据库中的数据。

我遇到的实际问题:

  • 编写一个尝试解决所有类似错误的通用脚本可能会产生意想不到的后果(例如,匹配不同但恰好具有相似名称的城市)。
  • 复制和修改数据可能会造成混乱,例如:
    • 再次生成它会破坏所有修复。
    • 当不同种类的错误较多时,会导致同一文件的副本过多,并且很难全部跟踪。
  • 编写脚本来修改特定条目似乎是最好的,但与打开 CSV 并修复它相比存在开销(但仍然似乎是最好的);或者我们需要创建更多的数据副本(如前一点)或者每次加载数据时都运行脚本。

在这种情况下,最佳实践是什么?

编辑:问题在于工作流程,而不是是否使用它。

(在我的特殊情况下,我不希望最终用户看到拼写错误的城市,更糟糕的是,看到同一城市但拼写不同的两个数据点;数据很小,大约 500 个不同的城市,所以手动更正确实有意义。)

4个回答

1.不要修改原始数据

保持原始数据源完好无损很重要。您可能会发现您对数据所做的更新无效。您可能还会找到一种更有效的更新方法,并且您将希望对这些更新进行回归测试。

始终使用数据副本,并添加包含任何已处理更正的列/属性/元数据。

例如,如果您的数据是一个 .csv 文件,其中的城市名称包含多个拼写错误:

1. Copy the .csv to a new file
2. Add a column for containing "adjusted_city_name"
3. Copy data from the city_name column to the 
   adjusted_city_name column and make corrections in that column.

2. 记录提议的更改

您想要对数据进行的任何更改都应记录在案,以便可以继续复制它们。

每次更改文档时的版本控制和时间戳。这将有助于日后进行故障排除。

明确。不要简单地陈述“正确的大小写问题”,陈述“确保每个城市名称的第一个字母以大写字母开头,其余字母小写”。

使用为管理数据清理而构建的任何自动化例程的引用更新文档。

3. 确定标准的数据清洗技术

无论您使用 perl、python、java、特定实用程序、手动过程还是其他东西都不是问题。问题是将来您希望将数据清理过程交给其他人。如果他们必须了解 12 种不同的数据清理技术,那么委派清理过程将非常困难。

4. 标准化工作流程

应该有一种标准的方式来处理新数据。理想情况下,这将像将文件放到特定位置一样简单,并且可预测的自动化过程会对其进行清理,并将清理过的数据集移交给下一个处理步骤。

5. 做尽可能少的改变是绝对必要的

进行容错分析总是比对数据做出假设更好。

6.避免手动更新

这总是很诱人,但人们容易出错,这又使委派变得困难。

手动处理注意事项

为了更完整地解决关于是否有一种“好”的手动处理方式的原始问题,我会说不,没有。我的回答是凭经验得出的,不是我随便做出的。

由于客户坚持认为手动数据清理过程很好并且可以在内部处理,我有不止一个项目浪费了几天的时间。您不希望您的项目依赖于单个人来完成不同规模的基于判断的任务。

让个人根据他们将要做什么来构建和记录规则集比让他们手动清理数据要好得多。(然后自动化该规则集)

如果自动化最终使您失败或根本不可能,那么将规则集委派给没有特定领域知识的其他人的能力至关重要。

最后,可以将诸如正确城市名称之类的例程应用于其他数据集。

即使您正在手动有效地修改某些记录,就像您给出的城市名称示例一样,我也建议您在代码中进行。强烈喜欢代码而不是手动调整记录的原因是代码使结果可重现。您希望确保始终可以从原始数据到最终结果,而无需任何人工干预。

这是一个简单的例子。假设我在 pandas 数据框中有一个城市名称列表,并且我确定它们都应该是“omaha”(您需要绝对确定,因为手动更改值充满了危险)。但相反,我有以下字符串:

pd.unique(data.city)
array(['omaha', 'omahd', 'imaha', 'omaka'], dtype=object)

您可以像这样进行更改:

data.city.values[data.city.values == 'omahd'] = 'omaha'
data.city.values[data.city.values == 'imaha'] = 'omaha'
data.city.values[data.city.values == 'omaka'] = 'omaha'

该代码很难看,但是如果您在相同的原始数据集上运行它,您将始终得到相同的结果。

除了之前的优秀答案,我想推荐两篇关于数据清洗的论文。它们并不特定于手动数据清理,但考虑到在代码中表达手动数据转换的好处和建议(我完全同意),这些资源可能同样有价值。此外,尽管以下论文在某种程度上侧重于 R,但我相信数据清理的一般思想工作流程可以很容易地提取出来,并且同样适用于非 R 环境。

第一篇论文介绍了整洁数据的概念,以及在数据清理中使用标准和特定 R 包的示例和最佳实践:http: //vita.had.co.nz/papers/tidy-data.pdf

以下论文介绍了 R 中数据清理的全面且连贯的方法,包括示例,以及对 R 中数据清理的工作流程框架)的描述,我强烈推荐:http://cran.r- project.org/doc/contrib/de_Jonge+van_der_Loo-Introduction_to_data_cleaning_with_R.pdf

正如许多人所回答的那样,最好避免手动完成任何事情,因为它的可重复性/可记录性较差。不过,您关于编写脚本与打开和修复文件的开销的观点是有效的。

最佳实践通常是

  • 保留未修改的数据版本
  • 构建数据的工作副本并修复错误
  • 有办法从原始数据重新创建工作副本

最后一点可以用脚本来完成。然后确保根据需要只修改要修改的数据,并以这样的方式编写脚本,即通过修改脚本添加修复与直接修改数据一样简单。

如果您的数据位于文件中,您还可以使用差异/补丁来存储原始数据以及生成工作数据所需的补丁。要生成它们,请复制您的工作副本,执行更改,提取差异/补丁,保存并删除以前的工作副本。